(e.g. -?\d{1,3}(?:\.\d+)deg, etc. : https://developer.mozilla.org/docs/Web/CSS/angle )
19 | GradientContainer.REGEXP_COLORSTOP = /^\s*(rgba?\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3}(?:,\s*[0-9\.]+)?\s*\)|[a-z]{3,20}|#[a-f0-9]{3,6})(?:\s+(\d{1,3}(?:\.\d+)?)(%|px)?)?(?:\s|$)/i;
20 |
21 | module.exports = GradientContainer;
22 |
--------------------------------------------------------------------------------
/src/dummyimagecontainer.js:
--------------------------------------------------------------------------------
1 | var log = require('./log');
2 | var smallImage = require('./utils').smallImage;
3 |
4 | function DummyImageContainer(src) {
5 | this.src = src;
6 | log("DummyImageContainer for", src);
7 | if (!this.promise || !this.image) {
8 | log("Initiating DummyImageContainer");
9 | DummyImageContainer.prototype.image = new Image();
10 | var image = this.image;
11 | DummyImageContainer.prototype.promise = new Promise(function(resolve, reject) {
12 | image.onload = resolve;
13 | image.onerror = reject;
14 | image.src = smallImage();
15 | if (image.complete === true) {
16 | resolve(image);
17 | }
18 | });
19 | }
20 | }
21 |
22 | module.exports = DummyImageContainer;
23 |
--------------------------------------------------------------------------------
/tests/cases/zindex/z-index13.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | text above children with negative z-index; z-index tests #13
5 |
6 |
7 |
25 |
26 |
27 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/tests/cases/images/canvas.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Image tests
5 |
6 |
7 |
8 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/tests/cases/zindex/z-index6.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | z-index tests #6
5 |
6 |
7 |
27 |
28 |
29 | z-index:0
30 | default z-index
31 | z-index:1
32 |
33 |
34 |
--------------------------------------------------------------------------------
/tests/cases/zindex/z-index5.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | z-index tests #5
5 |
6 |
7 |
24 |
25 |
26 |
27 | LEVEL #1
28 |
29 |
30 |
31 | LEVEL #1
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src/svgnodecontainer.js:
--------------------------------------------------------------------------------
1 | var SVGContainer = require('./svgcontainer');
2 |
3 | function SVGNodeContainer(node, _native) {
4 | this.src = node;
5 | this.image = null;
6 | var self = this;
7 |
8 | this.promise = _native ? new Promise(function(resolve, reject) {
9 | self.image = new Image();
10 | self.image.onload = resolve;
11 | self.image.onerror = reject;
12 | self.image.src = "data:image/svg+xml," + (new XMLSerializer()).serializeToString(node);
13 | if (self.image.complete === true) {
14 | resolve(self.image);
15 | }
16 | }) : this.hasFabric().then(function() {
17 | return new Promise(function(resolve) {
18 | window.html2canvas.svg.fabric.parseSVGDocument(node, self.createCanvas.call(self, resolve));
19 | });
20 | });
21 | }
22 |
23 | SVGNodeContainer.prototype = Object.create(SVGContainer.prototype);
24 |
25 | module.exports = SVGNodeContainer;
26 |
--------------------------------------------------------------------------------
/tests/cases/visibility.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Visible elements tests
5 |
6 |
7 |
12 |
13 |
14 |
15 | Display:none and visible:hidden tests
16 | This should be visible
17 | display:none, This should be hidden
18 | visibility:hidden, This should be hidden
19 |
20 | display:none, This should be hidden
21 | visibility:hidden, This should be hidden
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/tests/cases/zindex/z-index4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | z-index tests #4
5 |
6 |
7 |
25 |
26 |
27 |
28 | LEVEL #1
29 |
30 |
31 |
32 | LEVEL #1
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/tests/cases/zindex/z-index16.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Z-order positioning
5 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
24 | This text will overlay the butterfly image.
25 |
26 |
27 |
28 | This text will be beneath everything.
29 |
30 |
31 |
33 | This text will underlay text1, but overlay the butterfly image
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/textcontainer.js:
--------------------------------------------------------------------------------
1 | var NodeContainer = require('./nodecontainer');
2 |
3 | function TextContainer(node, parent) {
4 | NodeContainer.call(this, node, parent);
5 | }
6 |
7 | TextContainer.prototype = Object.create(NodeContainer.prototype);
8 |
9 | TextContainer.prototype.applyTextTransform = function() {
10 | this.node.data = this.transform(this.parent.css("textTransform"));
11 | };
12 |
13 | TextContainer.prototype.transform = function(transform) {
14 | var text = this.node.data;
15 | switch(transform){
16 | case "lowercase":
17 | return text.toLowerCase();
18 | case "capitalize":
19 | return text.replace(/(^|\s|:|-|\(|\))([a-z])/g, capitalize);
20 | case "uppercase":
21 | return text.toUpperCase();
22 | default:
23 | return text;
24 | }
25 | };
26 |
27 | function capitalize(m, p1, p2) {
28 | if (m.length > 0) {
29 | return p1 + p2.toUpperCase();
30 | }
31 | }
32 |
33 | module.exports = TextContainer;
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012 Niklas von Hertzen
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/tests/rangetest.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Range tests
5 |
6 |
11 |
12 |
13 |
14 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/tests/cases/border/dashed.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Borders tests
5 |
6 |
7 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/tests/cases/border/dotted.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Borders tests
5 |
6 |
7 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/tests/cases/border/double.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Borders tests
5 |
6 |
7 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/tests/cases/border/solid.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Borders tests
5 |
6 |
7 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/tests/cases/zindex/z-index12.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 | Negative z-indexes
7 |
8 |
9 |
35 |
36 |
37 |
38 |
39 |
Div Element #2
40 |
41 |
42 |
Div Element #3
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/tests/cases/google-maps.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | google maps
6 |
9 |
10 |
11 |
23 |
24 |
25 |
26 |
Google maps
27 |
28 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/tests/cases/zindex/z-index11.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 | static position inside position relative
7 |
8 |
9 |
30 |
31 |
32 |
33 |
34 |
Div Element #1
35 |
position: relative;
36 |
37 |
Div Element #2
38 |
position: static;
39 |
40 |
41 |
Div Element #3
42 | float: left;
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/tests/cases/images/svg/inline.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Inline svg
5 |
6 |
7 |
8 |
9 |
10 | Inline svg image:
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/tests/cases/images/images.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Image tests
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/tests/cases/images/svg/node.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SVG node
5 |
6 |
7 |
8 |
9 | SVG node image:
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '4.0'
4 | env:
5 | global:
6 | - secure: eW41gIqOizwO4pTgWnAAbW75AP7F+CK9qfSed/fSh4sJ9HWMIY1YRIaY8gjr+6jV/f7XVHcXuym6ZxgINYSkVKbF1JKxBJNLOXtSgNbVHSic58pYFvUjwxIBI9aPig9uux1+DbnpWqXFDTcACJSevQZE0xwmjdrSkDLgB0G34v8=
7 | - secure: Y2Av+Gd3z9uQEB36GwdOOuGka0hx0/HeitASEo59z934O8RxnmN9eNTXS7dDT3XtKtwxIyLTOEpS7qlRdWahH28hr/dS4xJj6ao58C+1xMcDs6NAPGmDxUlcJWpcGEsnjmXjQCc3fBioSTdpIBrK/gdvgpNh77UKG74Sk7Z+YGk=
8 | - secure: YI+YbTOGf2x4fPMKW+KhJiZWswoXT6xOKGwLfsQsVwmFX1LerJouil5D5iYOQuL4FE3pNaoJSNakIsokJQuGKJMmnPc8rdhMZuBJBk6MRghurE2Xe9qBHfuUBPlfD61nARESm4WDcyMwM0QVYaOKeY6aIpZ91qbUbyc60EEx3C4=
9 | addons:
10 | sauce_connect: true
11 | before_script:
12 | - npm install -g grunt-cli
13 | - npm install -g uglify-js
14 | notifications:
15 | webhooks:
16 | urls:
17 | - https://webhooks.gitter.im/e/2b007d4f86de89588804
18 | on_success: always
19 | on_failure: always
20 | on_start: false
21 | deploy:
22 | - provider: npm
23 | email: niklasvh@gmail.com
24 | api_key:
25 | secure: G/Szpr8q4/D6hp+H/Z9yyluUXtHAwf7LLa1Y07X59/Enlj1h7V5fQ7AW4/iAVM3XbIsrCPWR3dJU9g/ZxpxFg4OovIHVpS2Jr/mahtPYWdHR3pWuSmMW8QD+Twnq2VAFwSgg5Oumq3QxhX3YbCOnZox6+6Uviqk8FO7Z5B0RwW4=
26 | on:
27 | tags: true
28 | branch: master
29 | repo: niklasvh/html2canvas
30 |
--------------------------------------------------------------------------------
/tests/cases/text/shadow.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Text shadow tests
5 |
6 |
7 |
31 |
32 |
33 |
34 |
35 | Some text followed by text with shadow followed by more text without shadow.
36 | Multi text shadow and some more text without shadow
37 |
38 |
39 | testing with transparent
40 | testing with low opacity
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/tests/cases/list/decimal-leading-zero.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | List tests
5 |
6 |
7 |
8 |
16 |
17 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/tests/cases/list/decimal.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | List tests
5 |
6 |
7 |
8 |
16 |
17 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/tests/cases/list/lower-alpha.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | List tests
5 |
6 |
7 |
8 |
16 |
17 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/tests/cases/list/upper-roman.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | List tests
5 |
6 |
7 |
8 |
16 |
17 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/tests/cases/border/inset.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Borders tests
5 |
6 |
7 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/tests/cases/text/underline-lineheight.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Text-decoration:underline tests
5 |
6 |
7 |
19 |
20 |
43 |
44 |
45 |
46 | Creating content through JavaScript
47 |
48 |
49 |
--------------------------------------------------------------------------------
/tests/cases/text/underline.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Text-decoration:underline tests
5 |
6 |
7 |
19 |
20 |
44 |
45 |
46 |
47 | Creating content through JavaScript
48 |
49 |
50 |
--------------------------------------------------------------------------------
/tests/cases/text/linethrough.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Text-decoration:line-through tests
5 |
6 |
7 |
18 |
19 |
44 |
45 |
46 |
47 | Creating content through JavaScript
48 |
49 |
50 |
--------------------------------------------------------------------------------
/tests/cases/background/multi.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Background attribute tests
5 |
6 |
7 |
39 |
40 |
41 |
42 |
43 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/src/pseudoelementcontainer.js:
--------------------------------------------------------------------------------
1 | var NodeContainer = require('./nodecontainer');
2 |
3 | function PseudoElementContainer(node, parent, type) {
4 | NodeContainer.call(this, node, parent);
5 | this.isPseudoElement = true;
6 | this.before = type === ":before";
7 | }
8 |
9 | PseudoElementContainer.prototype.cloneTo = function(stack) {
10 | PseudoElementContainer.prototype.cloneTo.call(this, stack);
11 | stack.isPseudoElement = true;
12 | stack.before = this.before;
13 | };
14 |
15 | PseudoElementContainer.prototype = Object.create(NodeContainer.prototype);
16 |
17 | PseudoElementContainer.prototype.appendToDOM = function() {
18 | if (this.before) {
19 | this.parent.node.insertBefore(this.node, this.parent.node.firstChild);
20 | } else {
21 | this.parent.node.appendChild(this.node);
22 | }
23 | this.parent.node.className += " " + this.getHideClass();
24 | };
25 |
26 | PseudoElementContainer.prototype.cleanDOM = function() {
27 | this.node.parentNode.removeChild(this.node);
28 | this.parent.node.className = this.parent.node.className.replace(this.getHideClass(), "");
29 | };
30 |
31 | PseudoElementContainer.prototype.getHideClass = function() {
32 | return this["PSEUDO_HIDE_ELEMENT_CLASS_" + (this.before ? "BEFORE" : "AFTER")];
33 | };
34 |
35 | PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE = "___html2canvas___pseudoelement_before";
36 | PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER = "___html2canvas___pseudoelement_after";
37 |
38 | module.exports = PseudoElementContainer;
39 |
--------------------------------------------------------------------------------
/src/framecontainer.js:
--------------------------------------------------------------------------------
1 | var utils = require('./utils');
2 | var getBounds = utils.getBounds;
3 | var loadUrlDocument = require('./proxy').loadUrlDocument;
4 |
5 | function FrameContainer(container, sameOrigin, options) {
6 | this.image = null;
7 | this.src = container;
8 | var self = this;
9 | var bounds = getBounds(container);
10 | this.promise = (!sameOrigin ? this.proxyLoad(options.proxy, bounds, options) : new Promise(function(resolve) {
11 | if (container.contentWindow.document.URL === "about:blank" || container.contentWindow.document.documentElement == null) {
12 | container.contentWindow.onload = container.onload = function() {
13 | resolve(container);
14 | };
15 | } else {
16 | resolve(container);
17 | }
18 | })).then(function(container) {
19 | var html2canvas = require('./core');
20 | return html2canvas(container.contentWindow.document.documentElement, {type: 'view', width: container.width, height: container.height, proxy: options.proxy, javascriptEnabled: options.javascriptEnabled, removeContainer: options.removeContainer, allowTaint: options.allowTaint, imageTimeout: options.imageTimeout / 2});
21 | }).then(function(canvas) {
22 | return self.image = canvas;
23 | });
24 | }
25 |
26 | FrameContainer.prototype.proxyLoad = function(proxy, bounds, options) {
27 | var container = this.src;
28 | return loadUrlDocument(container.src, proxy, container.ownerDocument, bounds.width, bounds.height, options);
29 | };
30 |
31 | module.exports = FrameContainer;
32 |
--------------------------------------------------------------------------------
/tests/cases/images/svg/base64.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Base64 svg
5 |
6 |
7 |
8 |
9 |
10 | Inline svg image:
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "html2canvas",
3 | "name": "html2canvas",
4 | "description": "Screenshots with JavaScript",
5 | "main": "dist/html2canvas.js",
6 | "version": "0.5.0-beta4",
7 | "author": {
8 | "name": "Niklas von Hertzen",
9 | "email": "niklasvh@gmail.com",
10 | "url": "http://hertzen.com"
11 | },
12 | "engines": {
13 | "node": ">=4.0.0"
14 | },
15 | "repository": {
16 | "type": "git",
17 | "url": "git@github.com:niklasvh/html2canvas.git"
18 | },
19 | "bugs": {
20 | "url": "https://github.com/niklasvh/html2canvas/issues"
21 | },
22 | "devDependencies": {
23 | "base64-arraybuffer": "^0.1.5",
24 | "bluebird": "^3.0.6",
25 | "browserify-derequire": "^0.9.4",
26 | "grunt": "^0.4.5",
27 | "grunt-browserify": "^4.0.1",
28 | "grunt-cli": "^0.1.13",
29 | "grunt-contrib-connect": "^0.11.2",
30 | "grunt-contrib-jshint": "^0.11.3",
31 | "grunt-contrib-uglify": "^0.11.0",
32 | "grunt-contrib-watch": "^0.6.1",
33 | "grunt-execute": "^0.2.2",
34 | "grunt-mocha-cli": "^1.12.0",
35 | "grunt-mocha-phantomjs": "^2.0.0",
36 | "html2canvas-proxy": "0.0.5",
37 | "humanize-duration": "^2.0.1",
38 | "lodash": "^3.10.1",
39 | "pngjs": "^2.2.0",
40 | "requirejs": "^2.1.20",
41 | "sauce-connect-launcher": "^0.13.0",
42 | "wd": "^0.4.0"
43 | },
44 | "scripts": {
45 | "test": "grunt travis --verbose",
46 | "start": "grunt server",
47 | "sauceconnect": "tests/sauceconnect.js"
48 | },
49 | "homepage": "http://html2canvas.hertzen.com",
50 | "license": "MIT"
51 | }
52 |
--------------------------------------------------------------------------------
/src/font.js:
--------------------------------------------------------------------------------
1 | var smallImage = require('./utils').smallImage;
2 |
3 | function Font(family, size) {
4 | var container = document.createElement('div'),
5 | img = document.createElement('img'),
6 | span = document.createElement('span'),
7 | sampleText = 'Hidden Text',
8 | baseline,
9 | middle;
10 |
11 | container.style.visibility = "hidden";
12 | container.style.fontFamily = family;
13 | container.style.fontSize = size;
14 | container.style.margin = 0;
15 | container.style.padding = 0;
16 |
17 | document.body.appendChild(container);
18 |
19 | img.src = smallImage();
20 | img.width = 1;
21 | img.height = 1;
22 |
23 | img.style.margin = 0;
24 | img.style.padding = 0;
25 | img.style.verticalAlign = "baseline";
26 |
27 | span.style.fontFamily = family;
28 | span.style.fontSize = size;
29 | span.style.margin = 0;
30 | span.style.padding = 0;
31 |
32 | span.appendChild(document.createTextNode(sampleText));
33 | container.appendChild(span);
34 | container.appendChild(img);
35 | baseline = (img.offsetTop - span.offsetTop) + 1;
36 |
37 | container.removeChild(span);
38 | container.appendChild(document.createTextNode(sampleText));
39 |
40 | container.style.lineHeight = "normal";
41 | img.style.verticalAlign = "super";
42 |
43 | middle = (img.offsetTop-container.offsetTop) + 1;
44 |
45 | document.body.removeChild(container);
46 |
47 | this.baseline = baseline;
48 | this.lineWidth = 1;
49 | this.middle = middle;
50 | }
51 |
52 | module.exports = Font;
53 |
--------------------------------------------------------------------------------
/tests/cases/pseudoelements.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Pseudoelement tests
5 |
6 |
7 |
46 |
47 |
48 |
49 |
50 | Content 1
51 | Content 2
52 |
53 |
54 |
55 | Content 1
56 | Content 2
57 |
58 |
59 |
60 | Content 1
61 | Content 2
62 |
63 |
64 |
65 | Content 1
66 | Content 2
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/src/support.js:
--------------------------------------------------------------------------------
1 | function Support(document) {
2 | this.rangeBounds = this.testRangeBounds(document);
3 | this.cors = this.testCORS();
4 | this.svg = this.testSVG();
5 | }
6 |
7 | Support.prototype.testRangeBounds = function(document) {
8 | var range, testElement, rangeBounds, rangeHeight, support = false;
9 |
10 | if (document.createRange) {
11 | range = document.createRange();
12 | if (range.getBoundingClientRect) {
13 | testElement = document.createElement('boundtest');
14 | testElement.style.height = "123px";
15 | testElement.style.display = "block";
16 | document.body.appendChild(testElement);
17 |
18 | range.selectNode(testElement);
19 | rangeBounds = range.getBoundingClientRect();
20 | rangeHeight = rangeBounds.height;
21 |
22 | if (rangeHeight === 123) {
23 | support = true;
24 | }
25 | document.body.removeChild(testElement);
26 | }
27 | }
28 |
29 | return support;
30 | };
31 |
32 | Support.prototype.testCORS = function() {
33 | return typeof((new Image()).crossOrigin) !== "undefined";
34 | };
35 |
36 | Support.prototype.testSVG = function() {
37 | var img = new Image();
38 | var canvas = document.createElement("canvas");
39 | var ctx = canvas.getContext("2d");
40 | img.src = "data:image/svg+xml, ";
41 |
42 | try {
43 | ctx.drawImage(img, 0, 0);
44 | canvas.toDataURL();
45 | } catch(e) {
46 | return false;
47 | }
48 | return true;
49 | };
50 |
51 | module.exports = Support;
52 |
--------------------------------------------------------------------------------
/tests/cases/transform/nested.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Nested transform tests
5 |
6 |
7 |
39 |
40 |
41 |
42 | First level content
with second level content
and third level content
, ending second
, ending first
43 | something else
44 |
45 |
46 |
--------------------------------------------------------------------------------
/tests/cases/text/fontawesome.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | fontawesome icons
6 |
7 |
8 |
9 |
10 |
11 | Fontawesome icons
12 |
13 |
fa-5x
14 |
15 |
16 | List icons
17 | can be used
18 | as bullets
19 | in lists
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | fa-twitter on fa-square-o
28 |
29 |
30 |
31 |
32 | fa-flag on fa-circle
33 |
34 |
35 |
36 |
37 | fa-terminal on fa-square
38 |
39 |
40 |
41 |
42 | fa-ban on fa-camera
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/examples/existing_canvas.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Using an existing canvas to draw on
6 |
19 |
20 |
21 | HTML content to render:
22 |
Render the content in this element only onto the existing canvas element
23 |
24 | Existing canvas:
25 |
26 |
27 | Run html2canvas
28 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/tests/cases/clip.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Inline text in the top element
5 |
6 |
7 |
19 |
20 |
21 |
22 | Some inline text
followed by text in span followed by more inline text.
23 |
Then a block level element.
24 | Then more inline text.
25 |
26 | Some inline text
followed by text in span followed by more inline text.
27 |
Then a block level element.
28 | Then more inline text.
29 |
30 | Some inline text
followed by text in span followed by more inline text.
31 |
Then a block level element.
32 | Then more inline text.
33 |
34 | Some inline text
followed by text in span followed by more inline text.
35 |
Then a block level element.
36 | Then more inline text.
37 |
38 |
39 | Some inline text
followed by text in span followed by more inline text.
40 |
Then a block level element.
41 | Then more inline text.
42 |
43 |