mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Compare commits
23 Commits
0.5.0-alph
...
v0.5.0-bet
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2a2ad9bb65 | ||
![]() |
81e60975cc | ||
![]() |
a0669300c4 | ||
![]() |
ba9758cf14 | ||
![]() |
aa05241ff8 | ||
![]() |
5b4a6c26ee | ||
![]() |
364a8aac1c | ||
![]() |
46078acf71 | ||
![]() |
4b37909f09 | ||
![]() |
90f9eeba83 | ||
![]() |
98ee30643a | ||
![]() |
a49c3a2320 | ||
![]() |
4b80102e77 | ||
![]() |
9201cf7e95 | ||
![]() |
c2baf42145 | ||
![]() |
d9a9615ed7 | ||
![]() |
585a96a918 | ||
![]() |
9a0d43d60b | ||
![]() |
3671de81f9 | ||
![]() |
f3b6df267e | ||
![]() |
60619dca72 | ||
![]() |
ed299b3db1 | ||
![]() |
c7e484af89 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,6 +1,7 @@
|
||||
/nbproject/
|
||||
image.jpg
|
||||
/.project
|
||||
dist/
|
||||
/.settings/
|
||||
node_modules/
|
||||
.envrc
|
||||
@@ -9,3 +10,4 @@ node_modules/
|
||||
*.iml
|
||||
.idea/
|
||||
.DS_Store
|
||||
npm-debug.log
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
||||
[submodule "src/fabric"]
|
||||
path = src/fabric
|
||||
url = https://github.com/kangax/fabric.js.git
|
||||
[submodule "src/punycode"]
|
||||
path = src/punycode
|
||||
url = https://github.com/bestiejs/punycode.js.git
|
||||
|
@@ -15,6 +15,5 @@
|
||||
"globals": {
|
||||
"jQuery": true
|
||||
},
|
||||
"predef": ["NodeParser", "NodeContainer", "Color", "StackingContext", "TextContainer", "PseudoElementContainer", "ImageLoader", "CanvasRenderer", "Renderer", "Support", "bind", "Promise", "getBounds", "offsetBounds", "XHR",
|
||||
"ImageContainer", "ProxyImageContainer", "DummyImageContainer", "Font", "FontMetrics", "GradientContainer", "LinearGradientContainer", "WebkitGradientContainer", "SVGContainer", "SVGNodeContainer", "FrameContainer", "html2canvas", "log", "smallImage", "parseBackgrounds", "loadUrlDocument", "decode64", "Proxy", "ProxyURL"]
|
||||
"predef": ["-Promise", "define"]
|
||||
}
|
||||
|
5
.npmignore
Normal file
5
.npmignore
Normal file
@@ -0,0 +1,5 @@
|
||||
tests/
|
||||
examples/
|
||||
Gruntfile.js
|
||||
bower.json
|
||||
src/
|
22
.travis.yml
22
.travis.yml
@@ -1,21 +1,29 @@
|
||||
---
|
||||
language: node_js
|
||||
node_js:
|
||||
- '0.10'
|
||||
env:
|
||||
global:
|
||||
- secure: "eW41gIqOizwO4pTgWnAAbW75AP7F+CK9qfSed/fSh4sJ9HWMIY1YRIaY8gjr+6jV/f7XVHcXuym6ZxgINYSkVKbF1JKxBJNLOXtSgNbVHSic58pYFvUjwxIBI9aPig9uux1+DbnpWqXFDTcACJSevQZE0xwmjdrSkDLgB0G34v8="
|
||||
- secure: "Y2Av+Gd3z9uQEB36GwdOOuGka0hx0/HeitASEo59z934O8RxnmN9eNTXS7dDT3XtKtwxIyLTOEpS7qlRdWahH28hr/dS4xJj6ao58C+1xMcDs6NAPGmDxUlcJWpcGEsnjmXjQCc3fBioSTdpIBrK/gdvgpNh77UKG74Sk7Z+YGk="
|
||||
- secure: "YI+YbTOGf2x4fPMKW+KhJiZWswoXT6xOKGwLfsQsVwmFX1LerJouil5D5iYOQuL4FE3pNaoJSNakIsokJQuGKJMmnPc8rdhMZuBJBk6MRghurE2Xe9qBHfuUBPlfD61nARESm4WDcyMwM0QVYaOKeY6aIpZ91qbUbyc60EEx3C4="
|
||||
- secure: eW41gIqOizwO4pTgWnAAbW75AP7F+CK9qfSed/fSh4sJ9HWMIY1YRIaY8gjr+6jV/f7XVHcXuym6ZxgINYSkVKbF1JKxBJNLOXtSgNbVHSic58pYFvUjwxIBI9aPig9uux1+DbnpWqXFDTcACJSevQZE0xwmjdrSkDLgB0G34v8=
|
||||
- secure: Y2Av+Gd3z9uQEB36GwdOOuGka0hx0/HeitASEo59z934O8RxnmN9eNTXS7dDT3XtKtwxIyLTOEpS7qlRdWahH28hr/dS4xJj6ao58C+1xMcDs6NAPGmDxUlcJWpcGEsnjmXjQCc3fBioSTdpIBrK/gdvgpNh77UKG74Sk7Z+YGk=
|
||||
- secure: YI+YbTOGf2x4fPMKW+KhJiZWswoXT6xOKGwLfsQsVwmFX1LerJouil5D5iYOQuL4FE3pNaoJSNakIsokJQuGKJMmnPc8rdhMZuBJBk6MRghurE2Xe9qBHfuUBPlfD61nARESm4WDcyMwM0QVYaOKeY6aIpZ91qbUbyc60EEx3C4=
|
||||
addons:
|
||||
sauce_connect: true
|
||||
before_script:
|
||||
- npm install -g grunt-cli
|
||||
- npm install -g uglify-js
|
||||
- npm install -g grunt-cli
|
||||
- npm install -g uglify-js
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/2b007d4f86de89588804
|
||||
- https://webhooks.gitter.im/e/2b007d4f86de89588804
|
||||
on_success: always
|
||||
on_failure: always
|
||||
on_start: false
|
||||
deploy:
|
||||
- provider: npm
|
||||
email: niklasvh@gmail.com
|
||||
api_key:
|
||||
secure: dot+HzIe3thKep5mz5pyNYQV1ZYiGlVQAWScmfYh75AtOCJQJGvvw1alwRZDL0Ykn/7LeftZik845INn8Al8h4OEUQyuq2WmybZ5zn7PsLXRes7FtlJeYERO79bV5P3aV4vq4QoaZkPB5jQ98CmgQ2/9xPB+1ogNd7fRfUpSvSI=
|
||||
on:
|
||||
tags: true
|
||||
branch: master
|
||||
repo: niklasvh/html2canvas
|
||||
|
@@ -1,5 +1,9 @@
|
||||
### Changelog ###
|
||||
|
||||
v0.5.0-alpha2 - 3.2.2015
|
||||
* Switch to using browserify for building
|
||||
* Fix (#517) Chrome stretches background images with 'auto' or single attributes
|
||||
|
||||
v0.5.0-alpha - 19.1.2015
|
||||
* Complete rewrite of library
|
||||
* Switched interface to return Promise
|
||||
|
35
Gruntfile.js
35
Gruntfile.js
@@ -8,9 +8,7 @@ module.exports = function(grunt) {
|
||||
banner: '/*\n <%= pkg.title || pkg.name %> <%= pkg.version %>' +
|
||||
'<%= pkg.homepage ? " <" + pkg.homepage + ">" : "" %>' + '\n' +
|
||||
' Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>' +
|
||||
'\n\n Released under <%= _.pluck(pkg.licenses, "type").join(", ") %> License\n*/\n',
|
||||
pre: '\n(function(window, document, exports, global, define, undefined){\n\n',
|
||||
post: '\n}).call({}, typeof(window) !== "undefined" ? window : undefined, typeof(document) !== "undefined" ? document : undefined);'
|
||||
'\n\n Released under <%= _.pluck(pkg.licenses, "type").join(", ") %> License\n*/\n'
|
||||
};
|
||||
|
||||
var browsers = {
|
||||
@@ -59,16 +57,15 @@ module.exports = function(grunt) {
|
||||
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
|
||||
concat: {
|
||||
browserify: {
|
||||
dist: {
|
||||
src: [
|
||||
'src/promise.js', 'src/fallback.js', 'src/punycode/punycode.js', 'src/core.js', 'src/*.js', 'src/renderers/*.js'
|
||||
],
|
||||
nonull: true,
|
||||
src: ['src/core.js'],
|
||||
dest: 'dist/<%= pkg.name %>.js',
|
||||
options:{
|
||||
banner: meta.banner + meta.pre,
|
||||
footer: meta.post
|
||||
options: {
|
||||
browserifyOptions: {
|
||||
standalone: 'html2canvas'
|
||||
},
|
||||
banner: meta.banner
|
||||
}
|
||||
},
|
||||
svg: {
|
||||
@@ -77,8 +74,10 @@ module.exports = function(grunt) {
|
||||
],
|
||||
dest: 'dist/<%= pkg.name %>.svg.js',
|
||||
options:{
|
||||
banner: meta.banner + '\n(function(window, document, exports, undefined){\n\n',
|
||||
footer: '\n}).call({}, window, document, html2canvas);'
|
||||
browserifyOptions: {
|
||||
standalone: 'html2canvas.svg'
|
||||
},
|
||||
banner: meta.banner
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -149,11 +148,11 @@ module.exports = function(grunt) {
|
||||
},
|
||||
uglify: {
|
||||
dist: {
|
||||
src: ['<%= concat.dist.dest %>'],
|
||||
src: ['<%= browserify.dist.dest %>'],
|
||||
dest: 'dist/<%= pkg.name %>.min.js'
|
||||
},
|
||||
svg: {
|
||||
src: ['<%= concat.svg.dest %>'],
|
||||
src: ['<%= browserify.svg.dest %>'],
|
||||
dest: 'dist/<%= pkg.name %>.svg.min.js'
|
||||
},
|
||||
options: {
|
||||
@@ -165,7 +164,7 @@ module.exports = function(grunt) {
|
||||
tasks: ['jshint', 'build']
|
||||
},
|
||||
jshint: {
|
||||
all: ['src/*.js', 'src/renderers/*.js', '!src/promise.js'],
|
||||
all: ['src/*.js', 'src/renderers/*.js'],
|
||||
options: grunt.file.readJSON('./.jshintrc')
|
||||
},
|
||||
mochacli: {
|
||||
@@ -204,9 +203,9 @@ module.exports = function(grunt) {
|
||||
});
|
||||
});
|
||||
|
||||
grunt.loadNpmTasks('grunt-browserify');
|
||||
grunt.loadNpmTasks('grunt-mocha-phantomjs');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-connect');
|
||||
@@ -214,7 +213,7 @@ module.exports = function(grunt) {
|
||||
grunt.loadNpmTasks('grunt-mocha-cli');
|
||||
|
||||
grunt.registerTask('server', ['connect:cors', 'connect:proxy', 'connect:altServer', 'connect:server']);
|
||||
grunt.registerTask('build', ['execute', 'concat', 'uglify']);
|
||||
grunt.registerTask('build', ['execute', 'browserify', 'uglify']);
|
||||
grunt.registerTask('default', ['jshint', 'build', 'mochacli', 'connect:altServer', 'mocha_phantomjs']);
|
||||
grunt.registerTask('travis', ['jshint', 'build', 'connect:altServer', 'connect:ci', 'connect:proxy', 'connect:cors', 'mocha_phantomjs', 'webdriver']);
|
||||
|
||||
|
2536
dist/html2canvas.js
vendored
2536
dist/html2canvas.js
vendored
File diff suppressed because it is too large
Load Diff
7
dist/html2canvas.min.js
vendored
7
dist/html2canvas.min.js
vendored
File diff suppressed because one or more lines are too long
1575
dist/html2canvas.svg.js
vendored
1575
dist/html2canvas.svg.js
vendored
File diff suppressed because it is too large
Load Diff
14
dist/html2canvas.svg.min.js
vendored
14
dist/html2canvas.svg.min.js
vendored
File diff suppressed because one or more lines are too long
17
package.json
17
package.json
@@ -2,8 +2,8 @@
|
||||
"title": "html2canvas",
|
||||
"name": "html2canvas",
|
||||
"description": "Screenshots with JavaScript",
|
||||
"main": "main.js",
|
||||
"version": "0.5.0-alpha1",
|
||||
"main": "dist/html2canvas.js",
|
||||
"version": "0.5.0-beta1",
|
||||
"author": {
|
||||
"name": "Niklas von Hertzen",
|
||||
"email": "niklasvh@gmail.com",
|
||||
@@ -12,7 +12,9 @@
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"dependencies": {},
|
||||
"dependencies": {
|
||||
"es6-promise": "^2.0.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:niklasvh/html2canvas.git"
|
||||
@@ -23,23 +25,26 @@
|
||||
"devDependencies": {
|
||||
"base64-arraybuffer": ">= 0.1.0",
|
||||
"bluebird": "^2.7.1",
|
||||
"bower": "^1.3.12",
|
||||
"grunt": "^0.4.5",
|
||||
"grunt-contrib-concat": "^0.5.0",
|
||||
"grunt-browserify": "^3.3.0",
|
||||
"grunt-contrib-connect": "^0.8.0",
|
||||
"grunt-contrib-jshint": "^0.10.0",
|
||||
"grunt-contrib-uglify": "^0.6.0",
|
||||
"grunt-contrib-watch": "^0.6.1",
|
||||
"grunt-execute": "^0.2.2",
|
||||
"grunt-mocha-cli": "^1.12.0",
|
||||
"grunt-mocha-phantomjs": "^0.6.0",
|
||||
"grunt-mocha-phantomjs": "^2.0.0",
|
||||
"html2canvas-proxy": "0.0.5",
|
||||
"humanize-duration": "^2.0.1",
|
||||
"lodash": "^2.4.1",
|
||||
"png-js": ">= 0.1.1",
|
||||
"requirejs": "^2.1.20",
|
||||
"wd": "^0.2.21"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "grunt travis --verbose"
|
||||
"test": "grunt travis --verbose",
|
||||
"postpublish": "bower register html2canvas git://github.com/niklasvh/html2canvas.git"
|
||||
},
|
||||
"homepage": "http://html2canvas.hertzen.com",
|
||||
"licenses": [
|
||||
|
105
src/clone.js
Normal file
105
src/clone.js
Normal file
@@ -0,0 +1,105 @@
|
||||
var log = require('./log');
|
||||
var Promise = require('./promise');
|
||||
|
||||
function restoreOwnerScroll(ownerDocument, x, y) {
|
||||
if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {
|
||||
ownerDocument.defaultView.scrollTo(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
function cloneCanvasContents(canvas, clonedCanvas) {
|
||||
try {
|
||||
if (clonedCanvas) {
|
||||
clonedCanvas.width = canvas.width;
|
||||
clonedCanvas.height = canvas.height;
|
||||
clonedCanvas.getContext("2d").putImageData(canvas.getContext("2d").getImageData(0, 0, canvas.width, canvas.height), 0, 0);
|
||||
}
|
||||
} catch(e) {
|
||||
log("Unable to copy canvas content from", canvas, e);
|
||||
}
|
||||
}
|
||||
|
||||
function cloneNode(node, javascriptEnabled) {
|
||||
var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
|
||||
|
||||
var child = node.firstChild;
|
||||
while(child) {
|
||||
if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {
|
||||
clone.appendChild(cloneNode(child, javascriptEnabled));
|
||||
}
|
||||
child = child.nextSibling;
|
||||
}
|
||||
|
||||
if (node.nodeType === 1) {
|
||||
clone._scrollTop = node.scrollTop;
|
||||
clone._scrollLeft = node.scrollLeft;
|
||||
if (node.nodeName === "CANVAS") {
|
||||
cloneCanvasContents(node, clone);
|
||||
} else if (node.nodeName === "TEXTAREA" || node.nodeName === "SELECT") {
|
||||
clone.value = node.value;
|
||||
}
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
function initNode(node) {
|
||||
if (node.nodeType === 1) {
|
||||
node.scrollTop = node._scrollTop;
|
||||
node.scrollLeft = node._scrollLeft;
|
||||
|
||||
var child = node.firstChild;
|
||||
while(child) {
|
||||
initNode(child);
|
||||
child = child.nextSibling;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function(ownerDocument, containerDocument, width, height, options, x ,y) {
|
||||
var documentElement = cloneNode(ownerDocument.documentElement, options.javascriptEnabled);
|
||||
var container = containerDocument.createElement("iframe");
|
||||
|
||||
container.className = "html2canvas-container";
|
||||
container.style.visibility = "hidden";
|
||||
container.style.position = "fixed";
|
||||
container.style.left = "-10000px";
|
||||
container.style.top = "0px";
|
||||
container.style.border = "0";
|
||||
container.width = width;
|
||||
container.height = height;
|
||||
container.scrolling = "no"; // ios won't scroll without it
|
||||
containerDocument.body.appendChild(container);
|
||||
|
||||
return new Promise(function(resolve) {
|
||||
var documentClone = container.contentWindow.document;
|
||||
|
||||
/* 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
|
||||
*/
|
||||
container.contentWindow.onload = container.onload = function() {
|
||||
var interval = setInterval(function() {
|
||||
if (documentClone.body.childNodes.length > 0) {
|
||||
initNode(documentClone.documentElement);
|
||||
clearInterval(interval);
|
||||
if (options.type === "view") {
|
||||
container.contentWindow.scrollTo(x, y);
|
||||
if ((/(iPad|iPhone|iPod)/g).test(navigator.userAgent) && (container.contentWindow.scrollY !== y || container.contentWindow.scrollX !== x)) {
|
||||
documentClone.documentElement.style.top = (-y) + "px";
|
||||
documentClone.documentElement.style.left = (-x) + "px";
|
||||
documentClone.documentElement.style.position = 'absolute';
|
||||
}
|
||||
}
|
||||
resolve(container);
|
||||
}
|
||||
}, 50);
|
||||
};
|
||||
|
||||
documentClone.open();
|
||||
documentClone.write("<!DOCTYPE html><html></html>");
|
||||
// Chrome scrolls the parent document for some reason after the write to the cloned window???
|
||||
restoreOwnerScroll(ownerDocument, x, y);
|
||||
documentClone.replaceChild(documentClone.adoptNode(documentElement), documentClone.documentElement);
|
||||
documentClone.close();
|
||||
});
|
||||
};
|
@@ -268,3 +268,4 @@ var colors = {
|
||||
"yellowgreen": [154, 205, 50]
|
||||
};
|
||||
|
||||
module.exports = Color;
|
||||
|
195
src/core.js
195
src/core.js
@@ -1,9 +1,19 @@
|
||||
var Promise = require('./promise');
|
||||
var Support = require('./support');
|
||||
var CanvasRenderer = require('./renderers/canvas');
|
||||
var ImageLoader = require('./imageloader');
|
||||
var NodeParser = require('./nodeparser');
|
||||
var NodeContainer = require('./nodecontainer');
|
||||
var log = require('./log');
|
||||
var utils = require('./utils');
|
||||
var createWindowClone = require('./clone');
|
||||
var loadUrlDocument = require('./proxy').loadUrlDocument;
|
||||
var getBounds = utils.getBounds;
|
||||
|
||||
var html2canvasNodeAttribute = "data-html2canvas-node";
|
||||
var html2canvasCanvasCloneAttribute = "data-html2canvas-canvas-clone";
|
||||
var html2canvasCanvasCloneIndex = 0;
|
||||
var html2canvasCloneIndex = 0;
|
||||
|
||||
window.html2canvas = function(nodeList, options) {
|
||||
function html2canvas(nodeList, options) {
|
||||
var index = html2canvasCloneIndex++;
|
||||
options = options || {};
|
||||
if (options.logging) {
|
||||
@@ -39,10 +49,25 @@ window.html2canvas = function(nodeList, options) {
|
||||
}
|
||||
return canvas;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
window.html2canvas.punycode = this.punycode;
|
||||
window.html2canvas.proxy = {};
|
||||
html2canvas.Promise = Promise;
|
||||
html2canvas.CanvasRenderer = CanvasRenderer;
|
||||
html2canvas.NodeContainer = NodeContainer;
|
||||
html2canvas.log = log;
|
||||
html2canvas.utils = utils;
|
||||
|
||||
var html2canvasExport = (typeof(document) === "undefined" || typeof(Object.create) !== "function" || typeof(document.createElement("canvas").getContext) !== "function") ? function() {
|
||||
return Promise.reject("No canvas support");
|
||||
} : html2canvas;
|
||||
|
||||
module.exports = html2canvasExport;
|
||||
|
||||
if (typeof(define) === 'function' && define.amd) {
|
||||
define('html2canvas', [], function() {
|
||||
return html2canvasExport;
|
||||
});
|
||||
}
|
||||
|
||||
function renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) {
|
||||
return createWindowClone(document, document, windowWidth, windowHeight, options, document.defaultView.pageXOffset, document.defaultView.pageYOffset).then(function(container) {
|
||||
@@ -122,164 +147,6 @@ function documentHeight (doc) {
|
||||
);
|
||||
}
|
||||
|
||||
function smallImage() {
|
||||
return "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
||||
}
|
||||
|
||||
function isIE9() {
|
||||
return document.documentMode && document.documentMode <= 9;
|
||||
}
|
||||
|
||||
// https://github.com/niklasvh/html2canvas/issues/503
|
||||
function cloneNodeIE9(node, javascriptEnabled) {
|
||||
var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
|
||||
|
||||
var child = node.firstChild;
|
||||
while(child) {
|
||||
if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {
|
||||
clone.appendChild(cloneNodeIE9(child, javascriptEnabled));
|
||||
}
|
||||
child = child.nextSibling;
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
function createWindowClone(ownerDocument, containerDocument, width, height, options, x ,y) {
|
||||
labelCanvasElements(ownerDocument);
|
||||
var documentElement = isIE9() ? cloneNodeIE9(ownerDocument.documentElement, options.javascriptEnabled) : ownerDocument.documentElement.cloneNode(true);
|
||||
var container = containerDocument.createElement("iframe");
|
||||
|
||||
container.className = "html2canvas-container";
|
||||
container.style.visibility = "hidden";
|
||||
container.style.position = "fixed";
|
||||
container.style.left = "-10000px";
|
||||
container.style.top = "0px";
|
||||
container.style.border = "0";
|
||||
container.width = width;
|
||||
container.height = height;
|
||||
container.scrolling = "no"; // ios won't scroll without it
|
||||
containerDocument.body.appendChild(container);
|
||||
|
||||
return new Promise(function(resolve) {
|
||||
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
|
||||
if window url is about:blank, we can assign the url to current by writing onto the document
|
||||
*/
|
||||
container.contentWindow.onload = container.onload = function() {
|
||||
var interval = setInterval(function() {
|
||||
if (documentClone.body.childNodes.length > 0) {
|
||||
cloneCanvasContents(ownerDocument, documentClone);
|
||||
clearInterval(interval);
|
||||
if (options.type === "view") {
|
||||
container.contentWindow.scrollTo(x, y);
|
||||
}
|
||||
resolve(container);
|
||||
}
|
||||
}, 50);
|
||||
};
|
||||
|
||||
documentClone.open();
|
||||
documentClone.write("<!DOCTYPE html><html></html>");
|
||||
// Chrome scrolls the parent document for some reason after the write to the cloned window???
|
||||
restoreOwnerScroll(ownerDocument, x, y);
|
||||
documentClone.replaceChild(options.javascriptEnabled === true ? documentClone.adoptNode(documentElement) : removeScriptNodes(documentClone.adoptNode(documentElement)), documentClone.documentElement);
|
||||
documentClone.close();
|
||||
});
|
||||
}
|
||||
|
||||
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) {
|
||||
if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {
|
||||
ownerDocument.defaultView.scrollTo(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
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, 0, 0);
|
||||
});
|
||||
}
|
||||
|
||||
function documentFromHTML(src) {
|
||||
return function(html) {
|
||||
var parser = new DOMParser(), doc;
|
||||
try {
|
||||
doc = parser.parseFromString(html, "text/html");
|
||||
} catch(e) {
|
||||
log("DOMParser not supported, falling back to createHTMLDocument");
|
||||
doc = document.implementation.createHTMLDocument("");
|
||||
try {
|
||||
doc.open();
|
||||
doc.write(html);
|
||||
doc.close();
|
||||
} catch(ee) {
|
||||
log("createHTMLDocument write not supported, falling back to document.body.innerHTML");
|
||||
doc.body.innerHTML = html; // ie9 doesnt support writing to documentElement
|
||||
}
|
||||
}
|
||||
|
||||
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++);
|
||||
});
|
||||
}
|
||||
|
||||
function cloneCanvasContents(ownerDocument, documentClone) {
|
||||
[].slice.call(ownerDocument.querySelectorAll("[" + html2canvasCanvasCloneAttribute + "]"), 0).forEach(function(canvas) {
|
||||
try {
|
||||
var clonedCanvas = documentClone.querySelector('[' + html2canvasCanvasCloneAttribute + '="' + canvas.getAttribute(html2canvasCanvasCloneAttribute) + '"]');
|
||||
if (clonedCanvas) {
|
||||
clonedCanvas.width = canvas.width;
|
||||
clonedCanvas.height = canvas.height;
|
||||
clonedCanvas.getContext("2d").putImageData(canvas.getContext("2d").getImageData(0, 0, canvas.width, canvas.height), 0, 0);
|
||||
}
|
||||
} catch(e) {
|
||||
log("Unable to copy canvas content from", canvas, e);
|
||||
}
|
||||
canvas.removeAttribute(html2canvasCanvasCloneAttribute);
|
||||
});
|
||||
}
|
||||
|
||||
function removeScriptNodes(parent) {
|
||||
[].slice.call(parent.childNodes, 0).filter(isElementNode).forEach(function(node) {
|
||||
if (node.tagName === "SCRIPT") {
|
||||
parent.removeChild(node);
|
||||
} else {
|
||||
removeScriptNodes(node);
|
||||
}
|
||||
});
|
||||
return parent;
|
||||
}
|
||||
|
||||
function isElementNode(node) {
|
||||
return node.nodeType === Node.ELEMENT_NODE;
|
||||
}
|
||||
|
||||
function absoluteUrl(url) {
|
||||
var link = document.createElement("a");
|
||||
link.href = url;
|
||||
|
@@ -1,3 +1,7 @@
|
||||
var Promise = require('./promise');
|
||||
var log = require('./log');
|
||||
var smallImage = require('./utils').smallImage;
|
||||
|
||||
function DummyImageContainer(src) {
|
||||
this.src = src;
|
||||
log("DummyImageContainer for", src);
|
||||
@@ -15,3 +19,5 @@ function DummyImageContainer(src) {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = DummyImageContainer;
|
||||
|
@@ -1,6 +0,0 @@
|
||||
if (typeof(document) === "undefined" || typeof(Object.create) !== "function" || typeof(document.createElement("canvas").getContext) !== "function") {
|
||||
(window || module.exports).html2canvas = function() {
|
||||
return Promise.reject("No canvas support");
|
||||
};
|
||||
return;
|
||||
}
|
@@ -1,3 +1,5 @@
|
||||
var smallImage = require('./utils').smallImage;
|
||||
|
||||
function Font(family, size) {
|
||||
var container = document.createElement('div'),
|
||||
img = document.createElement('img'),
|
||||
@@ -46,3 +48,5 @@ function Font(family, size) {
|
||||
this.lineWidth = 1;
|
||||
this.middle = middle;
|
||||
}
|
||||
|
||||
module.exports = Font;
|
||||
|
@@ -1,3 +1,5 @@
|
||||
var Font = require('./font');
|
||||
|
||||
function FontMetrics() {
|
||||
this.data = {};
|
||||
}
|
||||
@@ -8,3 +10,5 @@ FontMetrics.prototype.getMetrics = function(family, size) {
|
||||
}
|
||||
return this.data[family + "-" + size];
|
||||
};
|
||||
|
||||
module.exports = FontMetrics;
|
||||
|
@@ -1,3 +1,8 @@
|
||||
var utils = require('./utils');
|
||||
var Promise = require('./promise');
|
||||
var getBounds = utils.getBounds;
|
||||
var loadUrlDocument = require('./proxy').loadUrlDocument;
|
||||
|
||||
function FrameContainer(container, sameOrigin, options) {
|
||||
this.image = null;
|
||||
this.src = container;
|
||||
@@ -12,6 +17,7 @@ function FrameContainer(container, sameOrigin, options) {
|
||||
resolve(container);
|
||||
}
|
||||
})).then(function(container) {
|
||||
var html2canvas = require('./core');
|
||||
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});
|
||||
}).then(function(canvas) {
|
||||
return self.image = canvas;
|
||||
@@ -22,3 +28,5 @@ FrameContainer.prototype.proxyLoad = function(proxy, bounds, options) {
|
||||
var container = this.src;
|
||||
return loadUrlDocument(container.src, proxy, container.ownerDocument, bounds.width, bounds.height, options);
|
||||
};
|
||||
|
||||
module.exports = FrameContainer;
|
||||
|
@@ -1,3 +1,5 @@
|
||||
var Promise = require('./promise');
|
||||
|
||||
function GradientContainer(imageData) {
|
||||
this.src = imageData.value;
|
||||
this.colorStops = [];
|
||||
@@ -13,3 +15,5 @@ GradientContainer.prototype.TYPES = {
|
||||
LINEAR: 1,
|
||||
RADIAL: 2
|
||||
};
|
||||
|
||||
module.exports = GradientContainer;
|
||||
|
@@ -1,3 +1,5 @@
|
||||
var Promise = require('./promise');
|
||||
|
||||
function ImageContainer(src, cors) {
|
||||
this.src = src;
|
||||
this.image = new Image();
|
||||
@@ -15,3 +17,5 @@ function ImageContainer(src, cors) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = ImageContainer;
|
||||
|
@@ -1,3 +1,15 @@
|
||||
var Promise = require('./promise');
|
||||
var log = require('./log');
|
||||
var ImageContainer = require('./imagecontainer');
|
||||
var DummyImageContainer = require('./dummyimagecontainer');
|
||||
var ProxyImageContainer = require('./proxyimagecontainer');
|
||||
var FrameContainer = require('./framecontainer');
|
||||
var SVGContainer = require('./svgcontainer');
|
||||
var SVGNodeContainer = require('./svgnodecontainer');
|
||||
var LinearGradientContainer = require('./lineargradientcontainer');
|
||||
var WebkitGradientContainer = require('./webkitgradientcontainer');
|
||||
var bind = require('./utils').bind;
|
||||
|
||||
function ImageLoader(options, support) {
|
||||
this.link = null;
|
||||
this.options = options;
|
||||
@@ -142,3 +154,5 @@ ImageLoader.prototype.timeout = function(container, timeout) {
|
||||
});
|
||||
return promise;
|
||||
};
|
||||
|
||||
module.exports = ImageLoader;
|
||||
|
@@ -1,3 +1,8 @@
|
||||
var GradientContainer = require('./gradientcontainer');
|
||||
var Color = require('./color');
|
||||
|
||||
var COLOR_STOP_REGEXP = /^\s*(.*)\s*(\d{1,3})?(%|px)?$/;
|
||||
|
||||
function LinearGradientContainer(imageData) {
|
||||
GradientContainer.apply(this, arguments);
|
||||
this.type = this.TYPES.LINEAR;
|
||||
@@ -38,13 +43,15 @@ function LinearGradientContainer(imageData) {
|
||||
this.y1 = 1;
|
||||
}
|
||||
|
||||
this.colorStops = imageData.args.slice(hasDirection ? 1 : 0).map(function(colorStop) {
|
||||
var colorStopMatch = colorStop.match(this.stepRegExp);
|
||||
return {
|
||||
color: new Color(colorStopMatch[1]),
|
||||
stop: colorStopMatch[3] === "%" ? colorStopMatch[2] / 100 : null
|
||||
};
|
||||
}, this);
|
||||
this.colorStops = imageData.args.slice(hasDirection ? 1 : 0)
|
||||
.map(function(colorStop) { return colorStop.match(COLOR_STOP_REGEXP);})
|
||||
.filter(function(colorStopMatch) { return !!colorStopMatch;})
|
||||
.map(function(colorStopMatch) {
|
||||
return {
|
||||
color: new Color(colorStopMatch[1]),
|
||||
stop: colorStopMatch[3] === "%" ? colorStopMatch[2] / 100 : null
|
||||
};
|
||||
});
|
||||
|
||||
if (this.colorStops[0].stop === null) {
|
||||
this.colorStops[0].stop = 0;
|
||||
@@ -71,3 +78,5 @@ function LinearGradientContainer(imageData) {
|
||||
LinearGradientContainer.prototype = Object.create(GradientContainer.prototype);
|
||||
|
||||
LinearGradientContainer.prototype.stepRegExp = /((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/;
|
||||
|
||||
module.exports = LinearGradientContainer;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
function log() {
|
||||
module.exports = function() {
|
||||
if (window.html2canvas.logging && window.console && window.console.log) {
|
||||
Function.prototype.bind.call(window.console.log, (window.console)).apply(window.console, [(Date.now() - window.html2canvas.start) + "ms", "html2canvas:"].concat([].slice.call(arguments, 0)));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -1,3 +1,9 @@
|
||||
var Color = require('./color');
|
||||
var utils = require('./utils');
|
||||
var getBounds = utils.getBounds;
|
||||
var parseBackgrounds = utils.parseBackgrounds;
|
||||
var offsetBounds = utils.offsetBounds;
|
||||
|
||||
function NodeContainer(node, parent) {
|
||||
this.node = node;
|
||||
this.parent = parent;
|
||||
@@ -121,7 +127,7 @@ NodeContainer.prototype.cssList = function(property, index) {
|
||||
value = value[index || 0] || value[0] || 'auto';
|
||||
value = value.trim().split(' ');
|
||||
if (value.length === 1) {
|
||||
value = [value[0], value[0]];
|
||||
value = [value[0], isPercentage(value[0]) ? 'auto' : value[0]];
|
||||
}
|
||||
return value;
|
||||
};
|
||||
@@ -252,7 +258,7 @@ NodeContainer.prototype.getValue = function() {
|
||||
return value.length === 0 ? (this.node.placeholder || "") : value;
|
||||
};
|
||||
|
||||
NodeContainer.prototype.MATRIX_PROPERTY = /(matrix)\((.+)\)/;
|
||||
NodeContainer.prototype.MATRIX_PROPERTY = /(matrix|matrix3d)\((.+)\)/;
|
||||
NodeContainer.prototype.TEXT_SHADOW_PROPERTY = /((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g;
|
||||
NodeContainer.prototype.TEXT_SHADOW_VALUES = /(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g;
|
||||
NodeContainer.prototype.CLIP = /^rect\((\d+)px,? (\d+)px,? (\d+)px,? (\d+)px\)$/;
|
||||
@@ -267,6 +273,11 @@ function parseMatrix(match) {
|
||||
return match[2].split(",").map(function(s) {
|
||||
return parseFloat(s.trim());
|
||||
});
|
||||
} else if (match && match[1] === "matrix3d") {
|
||||
var matrix3d = match[2].split(",").map(function(s) {
|
||||
return parseFloat(s.trim());
|
||||
});
|
||||
return [matrix3d[0], matrix3d[1], matrix3d[4], matrix3d[5], matrix3d[12], matrix3d[13]];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,102 +285,6 @@ function isPercentage(value) {
|
||||
return value.toString().indexOf("%") !== -1;
|
||||
}
|
||||
|
||||
function parseBackgrounds(backgroundImage) {
|
||||
var whitespace = ' \r\n\t',
|
||||
method, definition, prefix, prefix_i, block, results = [],
|
||||
mode = 0, numParen = 0, quote, args;
|
||||
var appendResult = function() {
|
||||
if(method) {
|
||||
if (definition.substr(0, 1) === '"') {
|
||||
definition = definition.substr(1, definition.length - 2);
|
||||
}
|
||||
if (definition) {
|
||||
args.push(definition);
|
||||
}
|
||||
if (method.substr(0, 1) === '-' && (prefix_i = method.indexOf('-', 1 ) + 1) > 0) {
|
||||
prefix = method.substr(0, prefix_i);
|
||||
method = method.substr(prefix_i);
|
||||
}
|
||||
results.push({
|
||||
prefix: prefix,
|
||||
method: method.toLowerCase(),
|
||||
value: block,
|
||||
args: args,
|
||||
image: null
|
||||
});
|
||||
}
|
||||
args = [];
|
||||
method = prefix = definition = block = '';
|
||||
};
|
||||
args = [];
|
||||
method = prefix = definition = block = '';
|
||||
backgroundImage.split("").forEach(function(c) {
|
||||
if (mode === 0 && whitespace.indexOf(c) > -1) {
|
||||
return;
|
||||
}
|
||||
switch(c) {
|
||||
case '"':
|
||||
if(!quote) {
|
||||
quote = c;
|
||||
} else if(quote === c) {
|
||||
quote = null;
|
||||
}
|
||||
break;
|
||||
case '(':
|
||||
if(quote) {
|
||||
break;
|
||||
} else if(mode === 0) {
|
||||
mode = 1;
|
||||
block += c;
|
||||
return;
|
||||
} else {
|
||||
numParen++;
|
||||
}
|
||||
break;
|
||||
case ')':
|
||||
if (quote) {
|
||||
break;
|
||||
} else if(mode === 1) {
|
||||
if(numParen === 0) {
|
||||
mode = 0;
|
||||
block += c;
|
||||
appendResult();
|
||||
return;
|
||||
} else {
|
||||
numParen--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ',':
|
||||
if (quote) {
|
||||
break;
|
||||
} else if(mode === 0) {
|
||||
appendResult();
|
||||
return;
|
||||
} else if (mode === 1) {
|
||||
if (numParen === 0 && !method.match(/^url$/i)) {
|
||||
args.push(definition);
|
||||
definition = '';
|
||||
block += c;
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
block += c;
|
||||
if (mode === 0) {
|
||||
method += c;
|
||||
} else {
|
||||
definition += c;
|
||||
}
|
||||
});
|
||||
|
||||
appendResult();
|
||||
return results;
|
||||
}
|
||||
|
||||
function removePx(str) {
|
||||
return str.replace("px", "");
|
||||
}
|
||||
@@ -378,31 +293,4 @@ function asFloat(str) {
|
||||
return parseFloat(str);
|
||||
}
|
||||
|
||||
function getBounds(node) {
|
||||
if (node.getBoundingClientRect) {
|
||||
var clientRect = node.getBoundingClientRect();
|
||||
var width = node.offsetWidth == null ? clientRect.width : node.offsetWidth;
|
||||
return {
|
||||
top: clientRect.top,
|
||||
bottom: clientRect.bottom || (clientRect.top + clientRect.height),
|
||||
right: clientRect.left + width,
|
||||
left: clientRect.left,
|
||||
width: width,
|
||||
height: node.offsetHeight == null ? clientRect.height : node.offsetHeight
|
||||
};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
function offsetBounds(node) {
|
||||
var parent = node.offsetParent ? offsetBounds(node.offsetParent) : {top: 0, left: 0};
|
||||
|
||||
return {
|
||||
top: node.offsetTop + parent.top,
|
||||
bottom: node.offsetTop + node.offsetHeight + parent.top,
|
||||
right: node.offsetLeft + parent.left + node.offsetWidth,
|
||||
left: node.offsetLeft + parent.left,
|
||||
width: node.offsetWidth,
|
||||
height: node.offsetHeight
|
||||
};
|
||||
}
|
||||
module.exports = NodeContainer;
|
||||
|
@@ -1,3 +1,18 @@
|
||||
var log = require('./log');
|
||||
var punycode = require('punycode');
|
||||
var NodeContainer = require('./nodecontainer');
|
||||
var TextContainer = require('./textcontainer');
|
||||
var PseudoElementContainer = require('./pseudoelementcontainer');
|
||||
var FontMetrics = require('./fontmetrics');
|
||||
var Color = require('./color');
|
||||
var Promise = require('./promise');
|
||||
var StackingContext = require('./stackingcontext');
|
||||
var utils = require('./utils');
|
||||
var bind = utils.bind;
|
||||
var getBounds = utils.getBounds;
|
||||
var parseBackgrounds = utils.parseBackgrounds;
|
||||
var offsetBounds = utils.offsetBounds;
|
||||
|
||||
function NodeParser(element, renderer, support, imageLoader, options) {
|
||||
log("Starting NodeParser");
|
||||
this.renderer = renderer;
|
||||
@@ -418,9 +433,9 @@ NodeParser.prototype.paintFormValue = function(container) {
|
||||
|
||||
NodeParser.prototype.paintText = function(container) {
|
||||
container.applyTextTransform();
|
||||
var characters = window.html2canvas.punycode.ucs2.decode(container.node.data);
|
||||
var characters = punycode.ucs2.decode(container.node.data);
|
||||
var textList = (!this.options.letterRendering || noLetterSpacing(container)) && !hasUnicode(container.node.data) ? getWords(characters) : characters.map(function(character) {
|
||||
return window.html2canvas.punycode.ucs2.encode([character]);
|
||||
return punycode.ucs2.encode([character]);
|
||||
});
|
||||
|
||||
var weight = container.parent.fontWeight();
|
||||
@@ -602,14 +617,14 @@ function calculateCurvePoints(bounds, borderRadius, borders) {
|
||||
width = bounds.width,
|
||||
height = bounds.height,
|
||||
|
||||
tlh = borderRadius[0][0],
|
||||
tlv = borderRadius[0][1],
|
||||
trh = borderRadius[1][0],
|
||||
trv = borderRadius[1][1],
|
||||
brh = borderRadius[2][0],
|
||||
brv = borderRadius[2][1],
|
||||
blh = borderRadius[3][0],
|
||||
blv = borderRadius[3][1];
|
||||
tlh = borderRadius[0][0] < width / 2 ? borderRadius[0][0] : width / 2,
|
||||
tlv = borderRadius[0][1] < height / 2 ? borderRadius[0][1] : height / 2,
|
||||
trh = borderRadius[1][0] < width / 2 ? borderRadius[1][0] : width / 2,
|
||||
trv = borderRadius[1][1] < height / 2 ? borderRadius[1][1] : height / 2,
|
||||
brh = borderRadius[2][0] < width / 2 ? borderRadius[2][0] : width / 2,
|
||||
brv = borderRadius[2][1] < height / 2 ? borderRadius[2][1] : height / 2,
|
||||
blh = borderRadius[3][0] < width / 2 ? borderRadius[3][0] : width / 2,
|
||||
blv = borderRadius[3][1] < height / 2 ? borderRadius[3][1] : height / 2;
|
||||
|
||||
var topWidth = width - trh,
|
||||
rightHeight = height - brv,
|
||||
@@ -793,12 +808,6 @@ function hasOpacity(container) {
|
||||
return container.getOpacity() < 1;
|
||||
}
|
||||
|
||||
function bind(callback, context) {
|
||||
return function() {
|
||||
return callback.apply(context, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
function asInt(value) {
|
||||
return parseInt(value, 10);
|
||||
}
|
||||
@@ -826,7 +835,7 @@ function getWords(characters) {
|
||||
if (isWordBoundary(characters[i]) === onWordBoundary) {
|
||||
word = characters.splice(0, i);
|
||||
if (word.length) {
|
||||
words.push(window.html2canvas.punycode.ucs2.encode(word));
|
||||
words.push(punycode.ucs2.encode(word));
|
||||
}
|
||||
onWordBoundary =! onWordBoundary;
|
||||
i = 0;
|
||||
@@ -837,7 +846,7 @@ function getWords(characters) {
|
||||
if (i >= characters.length) {
|
||||
word = characters.splice(0, i);
|
||||
if (word.length) {
|
||||
words.push(window.html2canvas.punycode.ucs2.encode(word));
|
||||
words.push(punycode.ucs2.encode(word));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -857,3 +866,5 @@ function isWordBoundary(characterCode) {
|
||||
function hasUnicode(string) {
|
||||
return (/[^\u0000-\u00ff]/).test(string);
|
||||
}
|
||||
|
||||
module.exports = NodeParser;
|
||||
|
@@ -1,22 +1 @@
|
||||
/*!
|
||||
* @overview es6-promise - a tiny implementation of Promises/A+.
|
||||
* @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
|
||||
* @license Licensed under MIT license
|
||||
* See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE
|
||||
* @version 2.0.1
|
||||
*/
|
||||
|
||||
(function(){function r(a,b){n[l]=a;n[l+1]=b;l+=2;2===l&&A()}function s(a){return"function"===typeof a}function F(){return function(){process.nextTick(t)}}function G(){var a=0,b=new B(t),c=document.createTextNode("");b.observe(c,{characterData:!0});return function(){c.data=a=++a%2}}function H(){var a=new MessageChannel;a.port1.onmessage=t;return function(){a.port2.postMessage(0)}}function I(){return function(){setTimeout(t,1)}}function t(){for(var a=0;a<l;a+=2)(0,n[a])(n[a+1]),n[a]=void 0,n[a+1]=void 0;
|
||||
l=0}function p(){}function J(a,b,c,d){try{a.call(b,c,d)}catch(e){return e}}function K(a,b,c){r(function(a){var e=!1,f=J(c,b,function(c){e||(e=!0,b!==c?q(a,c):m(a,c))},function(b){e||(e=!0,g(a,b))});!e&&f&&(e=!0,g(a,f))},a)}function L(a,b){1===b.a?m(a,b.b):2===a.a?g(a,b.b):u(b,void 0,function(b){q(a,b)},function(b){g(a,b)})}function q(a,b){if(a===b)g(a,new TypeError("You cannot resolve a promise with itself"));else if("function"===typeof b||"object"===typeof b&&null!==b)if(b.constructor===a.constructor)L(a,
|
||||
b);else{var c;try{c=b.then}catch(d){v.error=d,c=v}c===v?g(a,v.error):void 0===c?m(a,b):s(c)?K(a,b,c):m(a,b)}else m(a,b)}function M(a){a.f&&a.f(a.b);x(a)}function m(a,b){void 0===a.a&&(a.b=b,a.a=1,0!==a.e.length&&r(x,a))}function g(a,b){void 0===a.a&&(a.a=2,a.b=b,r(M,a))}function u(a,b,c,d){var e=a.e,f=e.length;a.f=null;e[f]=b;e[f+1]=c;e[f+2]=d;0===f&&a.a&&r(x,a)}function x(a){var b=a.e,c=a.a;if(0!==b.length){for(var d,e,f=a.b,g=0;g<b.length;g+=3)d=b[g],e=b[g+c],d?C(c,d,e,f):e(f);a.e.length=0}}function D(){this.error=
|
||||
null}function C(a,b,c,d){var e=s(c),f,k,h,l;if(e){try{f=c(d)}catch(n){y.error=n,f=y}f===y?(l=!0,k=f.error,f=null):h=!0;if(b===f){g(b,new TypeError("A promises callback cannot return that same promise."));return}}else f=d,h=!0;void 0===b.a&&(e&&h?q(b,f):l?g(b,k):1===a?m(b,f):2===a&&g(b,f))}function N(a,b){try{b(function(b){q(a,b)},function(b){g(a,b)})}catch(c){g(a,c)}}function k(a,b,c,d){this.n=a;this.c=new a(p,d);this.i=c;this.o(b)?(this.m=b,this.d=this.length=b.length,this.l(),0===this.length?m(this.c,
|
||||
this.b):(this.length=this.length||0,this.k(),0===this.d&&m(this.c,this.b))):g(this.c,this.p())}function h(a){O++;this.b=this.a=void 0;this.e=[];if(p!==a){if(!s(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof h))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");N(this,a)}}var E=Array.isArray?Array.isArray:function(a){return"[object Array]"===
|
||||
Object.prototype.toString.call(a)},l=0,w="undefined"!==typeof window?window:{},B=w.MutationObserver||w.WebKitMutationObserver,w="undefined"!==typeof Uint8ClampedArray&&"undefined"!==typeof importScripts&&"undefined"!==typeof MessageChannel,n=Array(1E3),A;A="undefined"!==typeof process&&"[object process]"==={}.toString.call(process)?F():B?G():w?H():I();var v=new D,y=new D;k.prototype.o=function(a){return E(a)};k.prototype.p=function(){return Error("Array Methods must be provided an Array")};k.prototype.l=
|
||||
function(){this.b=Array(this.length)};k.prototype.k=function(){for(var a=this.length,b=this.c,c=this.m,d=0;void 0===b.a&&d<a;d++)this.j(c[d],d)};k.prototype.j=function(a,b){var c=this.n;"object"===typeof a&&null!==a?a.constructor===c&&void 0!==a.a?(a.f=null,this.g(a.a,b,a.b)):this.q(c.resolve(a),b):(this.d--,this.b[b]=this.h(a))};k.prototype.g=function(a,b,c){var d=this.c;void 0===d.a&&(this.d--,this.i&&2===a?g(d,c):this.b[b]=this.h(c));0===this.d&&m(d,this.b)};k.prototype.h=function(a){return a};
|
||||
k.prototype.q=function(a,b){var c=this;u(a,void 0,function(a){c.g(1,b,a)},function(a){c.g(2,b,a)})};var O=0;h.all=function(a,b){return(new k(this,a,!0,b)).c};h.race=function(a,b){function c(a){q(e,a)}function d(a){g(e,a)}var e=new this(p,b);if(!E(a))return (g(e,new TypeError("You must pass an array to race.")), e);for(var f=a.length,h=0;void 0===e.a&&h<f;h++)u(this.resolve(a[h]),void 0,c,d);return e};h.resolve=function(a,b){if(a&&"object"===typeof a&&a.constructor===this)return a;var c=new this(p,b);
|
||||
q(c,a);return c};h.reject=function(a,b){var c=new this(p,b);g(c,a);return c};h.prototype={constructor:h,then:function(a,b){var c=this.a;if(1===c&&!a||2===c&&!b)return this;var d=new this.constructor(p),e=this.b;if(c){var f=arguments[c-1];r(function(){C(c,d,f,e)})}else u(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}};var z={Promise:h,polyfill:function(){var a;a="undefined"!==typeof global?global:"undefined"!==typeof window&&window.document?window:self;"Promise"in a&&"resolve"in
|
||||
a.Promise&&"reject"in a.Promise&&"all"in a.Promise&&"race"in a.Promise&&function(){var b;new a.Promise(function(a){b=a});return s(b)}()||(a.Promise=h)}};"function"===typeof define&&define.amd?define(function(){return z}):"undefined"!==typeof module&&module.exports?module.exports=z:"undefined"!==typeof this&&(this.ES6Promise=z);}).call(window);
|
||||
if (window) {
|
||||
window.ES6Promise.polyfill();
|
||||
}
|
||||
|
||||
module.exports = require('es6-promise').Promise;
|
||||
|
51
src/proxy.js
51
src/proxy.js
@@ -1,4 +1,12 @@
|
||||
var Promise = require('./promise');
|
||||
var XHR = require('./xhr');
|
||||
var utils = require('./utils');
|
||||
var log = require('./log');
|
||||
var createWindowClone = require('./clone');
|
||||
var decode64 = utils.decode64;
|
||||
|
||||
function Proxy(src, proxyUrl, document) {
|
||||
var supportsCORS = ('withCredentials' in new XMLHttpRequest());
|
||||
if (!proxyUrl) {
|
||||
return Promise.reject("No proxy configured");
|
||||
}
|
||||
@@ -11,10 +19,8 @@ function Proxy(src, proxyUrl, document) {
|
||||
}
|
||||
var proxyCount = 0;
|
||||
|
||||
var supportsCORS = ('withCredentials' in new XMLHttpRequest());
|
||||
var supportsCORSImage = ('crossOrigin' in new Image());
|
||||
|
||||
function ProxyURL(src, proxyUrl, document) {
|
||||
var supportsCORSImage = ('crossOrigin' in new Image());
|
||||
var callback = createCallback(supportsCORSImage);
|
||||
var url = createProxyUrl(proxyUrl, src, callback);
|
||||
return (supportsCORSImage ? Promise.resolve(url) : jsonp(document, url, callback).then(function(response) {
|
||||
@@ -49,3 +55,42 @@ function createCallback(useCORS) {
|
||||
function createProxyUrl(proxyUrl, src, callback) {
|
||||
return proxyUrl + "?url=" + encodeURIComponent(src) + (callback.length ? "&callback=html2canvas.proxy." + callback : "");
|
||||
}
|
||||
|
||||
function documentFromHTML(src) {
|
||||
return function(html) {
|
||||
var parser = new DOMParser(), doc;
|
||||
try {
|
||||
doc = parser.parseFromString(html, "text/html");
|
||||
} catch(e) {
|
||||
log("DOMParser not supported, falling back to createHTMLDocument");
|
||||
doc = document.implementation.createHTMLDocument("");
|
||||
try {
|
||||
doc.open();
|
||||
doc.write(html);
|
||||
doc.close();
|
||||
} catch(ee) {
|
||||
log("createHTMLDocument write not supported, falling back to document.body.innerHTML");
|
||||
doc.body.innerHTML = html; // ie9 doesnt support writing to documentElement
|
||||
}
|
||||
}
|
||||
|
||||
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 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, 0, 0);
|
||||
});
|
||||
}
|
||||
|
||||
exports.Proxy = Proxy;
|
||||
exports.ProxyURL = ProxyURL;
|
||||
exports.loadUrlDocument = loadUrlDocument;
|
||||
|
@@ -1,5 +1,7 @@
|
||||
var ProxyURL = require('./proxy').ProxyURL;
|
||||
var Promise = require('./promise');
|
||||
|
||||
function ProxyImageContainer(src, proxy) {
|
||||
var script = document.createElement("script");
|
||||
var link = document.createElement("a");
|
||||
link.href = src;
|
||||
src = link.href;
|
||||
@@ -16,3 +18,5 @@ function ProxyImageContainer(src, proxy) {
|
||||
})['catch'](reject);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = ProxyImageContainer;
|
||||
|
@@ -1,3 +1,5 @@
|
||||
var NodeContainer = require('./nodecontainer');
|
||||
|
||||
function PseudoElementContainer(node, parent, type) {
|
||||
NodeContainer.call(this, node, parent);
|
||||
this.isPseudoElement = true;
|
||||
@@ -32,3 +34,5 @@ PseudoElementContainer.prototype.getHideClass = function() {
|
||||
|
||||
PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE = "___html2canvas___pseudoelement_before";
|
||||
PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER = "___html2canvas___pseudoelement_after";
|
||||
|
||||
module.exports = PseudoElementContainer;
|
||||
|
Submodule src/punycode deleted from 5c04e6fe95
@@ -1,3 +1,5 @@
|
||||
var log = require('./log');
|
||||
|
||||
function Renderer(width, height, images, options, document) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
@@ -102,3 +104,5 @@ Renderer.prototype.renderBackgroundRepeating = function(container, bounds, image
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Renderer;
|
||||
|
@@ -1,3 +1,7 @@
|
||||
var Renderer = require('../renderer');
|
||||
var LinearGradientContainer = require('../lineargradientcontainer');
|
||||
var log = require('../log');
|
||||
|
||||
function CanvasRenderer(width, height) {
|
||||
Renderer.apply(this, arguments);
|
||||
this.canvas = this.options.canvas || this.document.createElement("canvas");
|
||||
@@ -173,3 +177,5 @@ CanvasRenderer.prototype.resizeImage = function(imageContainer, size) {
|
||||
function hasEntries(array) {
|
||||
return array.length > 0;
|
||||
}
|
||||
|
||||
module.exports = CanvasRenderer;
|
||||
|
@@ -1,3 +1,5 @@
|
||||
var NodeContainer = require('./nodecontainer');
|
||||
|
||||
function StackingContext(hasOwnStacking, opacity, element, parent) {
|
||||
NodeContainer.call(this, element, parent);
|
||||
this.ownStacking = hasOwnStacking;
|
||||
@@ -12,3 +14,5 @@ StackingContext.prototype.getParentStack = function(context) {
|
||||
var parentStack = (this.parent) ? this.parent.stack : null;
|
||||
return parentStack ? (parentStack.ownStacking ? parentStack : parentStack.getParentStack(context)) : context.stack;
|
||||
};
|
||||
|
||||
module.exports = StackingContext;
|
||||
|
@@ -47,3 +47,5 @@ Support.prototype.testSVG = function() {
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
module.exports = Support;
|
||||
|
@@ -1,3 +1,7 @@
|
||||
var Promise = require('./promise');
|
||||
var XHR = require('./xhr');
|
||||
var decode64 = require('./utils').decode64;
|
||||
|
||||
function SVGContainer(src) {
|
||||
this.src = src;
|
||||
this.image = null;
|
||||
@@ -7,13 +11,13 @@ function SVGContainer(src) {
|
||||
return (self.isInline(src) ? Promise.resolve(self.inlineFormatting(src)) : XHR(src));
|
||||
}).then(function(svg) {
|
||||
return new Promise(function(resolve) {
|
||||
html2canvas.fabric.loadSVGFromString(svg, self.createCanvas.call(self, resolve));
|
||||
window.html2canvas.svg.fabric.loadSVGFromString(svg, self.createCanvas.call(self, resolve));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
SVGContainer.prototype.hasFabric = function() {
|
||||
return !html2canvas.fabric ? Promise.reject(new Error("html2canvas.svg.js is not loaded, cannot render svg")) : Promise.resolve();
|
||||
return !window.html2canvas.svg || !window.html2canvas.svg.fabric ? Promise.reject(new Error("html2canvas.svg.js is not loaded, cannot render svg")) : Promise.resolve();
|
||||
};
|
||||
|
||||
SVGContainer.prototype.inlineFormatting = function(src) {
|
||||
@@ -31,12 +35,12 @@ SVGContainer.prototype.isInline = function(src) {
|
||||
SVGContainer.prototype.createCanvas = function(resolve) {
|
||||
var self = this;
|
||||
return function (objects, options) {
|
||||
var canvas = new html2canvas.fabric.StaticCanvas('c');
|
||||
var canvas = new window.html2canvas.svg.fabric.StaticCanvas('c');
|
||||
self.image = canvas.lowerCanvasEl;
|
||||
canvas
|
||||
.setWidth(options.width)
|
||||
.setHeight(options.height)
|
||||
.add(html2canvas.fabric.util.groupSVGElements(objects, options))
|
||||
.add(window.html2canvas.svg.fabric.util.groupSVGElements(objects, options))
|
||||
.renderAll();
|
||||
resolve(canvas.lowerCanvasEl);
|
||||
};
|
||||
@@ -46,37 +50,4 @@ SVGContainer.prototype.decode64 = function(str) {
|
||||
return (typeof(window.atob) === "function") ? window.atob(str) : decode64(str);
|
||||
};
|
||||
|
||||
/*
|
||||
* base64-arraybuffer
|
||||
* https://github.com/niklasvh/base64-arraybuffer
|
||||
*
|
||||
* Copyright (c) 2012 Niklas von Hertzen
|
||||
* Licensed under the MIT license.
|
||||
*/
|
||||
|
||||
function decode64(base64) {
|
||||
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
var len = base64.length, i, encoded1, encoded2, encoded3, encoded4, byte1, byte2, byte3;
|
||||
|
||||
var output = "";
|
||||
|
||||
for (i = 0; i < len; i+=4) {
|
||||
encoded1 = chars.indexOf(base64[i]);
|
||||
encoded2 = chars.indexOf(base64[i+1]);
|
||||
encoded3 = chars.indexOf(base64[i+2]);
|
||||
encoded4 = chars.indexOf(base64[i+3]);
|
||||
|
||||
byte1 = (encoded1 << 2) | (encoded2 >> 4);
|
||||
byte2 = ((encoded2 & 15) << 4) | (encoded3 >> 2);
|
||||
byte3 = ((encoded3 & 3) << 6) | encoded4;
|
||||
if (encoded3 === 64) {
|
||||
output += String.fromCharCode(byte1);
|
||||
} else if (encoded4 === 64 || encoded4 === -1) {
|
||||
output += String.fromCharCode(byte1, byte2);
|
||||
} else{
|
||||
output += String.fromCharCode(byte1, byte2, byte3);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
module.exports = SVGContainer;
|
||||
|
@@ -1,9 +1,12 @@
|
||||
function SVGNodeContainer(node, native) {
|
||||
var SVGContainer = require('./svgcontainer');
|
||||
var Promise = require('./promise');
|
||||
|
||||
function SVGNodeContainer(node, _native) {
|
||||
this.src = node;
|
||||
this.image = null;
|
||||
var self = this;
|
||||
|
||||
this.promise = native ? new Promise(function(resolve, reject) {
|
||||
this.promise = _native ? new Promise(function(resolve, reject) {
|
||||
self.image = new Image();
|
||||
self.image.onload = resolve;
|
||||
self.image.onerror = reject;
|
||||
@@ -13,9 +16,11 @@ function SVGNodeContainer(node, native) {
|
||||
}
|
||||
}) : this.hasFabric().then(function() {
|
||||
return new Promise(function(resolve) {
|
||||
html2canvas.fabric.parseSVGDocument(node, self.createCanvas.call(self, resolve));
|
||||
window.html2canvas.svg.fabric.parseSVGDocument(node, self.createCanvas.call(self, resolve));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
SVGNodeContainer.prototype = Object.create(SVGContainer.prototype);
|
||||
|
||||
module.exports = SVGNodeContainer;
|
||||
|
@@ -1,3 +1,5 @@
|
||||
var NodeContainer = require('./nodecontainer');
|
||||
|
||||
function TextContainer(node, parent) {
|
||||
NodeContainer.call(this, node, parent);
|
||||
}
|
||||
@@ -27,3 +29,5 @@ function capitalize(m, p1, p2) {
|
||||
return p1 + p2.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TextContainer;
|
||||
|
169
src/utils.js
Normal file
169
src/utils.js
Normal file
@@ -0,0 +1,169 @@
|
||||
exports.smallImage = function smallImage() {
|
||||
return "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
||||
};
|
||||
|
||||
exports.bind = function(callback, context) {
|
||||
return function() {
|
||||
return callback.apply(context, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* base64-arraybuffer
|
||||
* https://github.com/niklasvh/base64-arraybuffer
|
||||
*
|
||||
* Copyright (c) 2012 Niklas von Hertzen
|
||||
* Licensed under the MIT license.
|
||||
*/
|
||||
|
||||
exports.decode64 = function(base64) {
|
||||
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
var len = base64.length, i, encoded1, encoded2, encoded3, encoded4, byte1, byte2, byte3;
|
||||
|
||||
var output = "";
|
||||
|
||||
for (i = 0; i < len; i+=4) {
|
||||
encoded1 = chars.indexOf(base64[i]);
|
||||
encoded2 = chars.indexOf(base64[i+1]);
|
||||
encoded3 = chars.indexOf(base64[i+2]);
|
||||
encoded4 = chars.indexOf(base64[i+3]);
|
||||
|
||||
byte1 = (encoded1 << 2) | (encoded2 >> 4);
|
||||
byte2 = ((encoded2 & 15) << 4) | (encoded3 >> 2);
|
||||
byte3 = ((encoded3 & 3) << 6) | encoded4;
|
||||
if (encoded3 === 64) {
|
||||
output += String.fromCharCode(byte1);
|
||||
} else if (encoded4 === 64 || encoded4 === -1) {
|
||||
output += String.fromCharCode(byte1, byte2);
|
||||
} else{
|
||||
output += String.fromCharCode(byte1, byte2, byte3);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
exports.getBounds = function(node) {
|
||||
if (node.getBoundingClientRect) {
|
||||
var clientRect = node.getBoundingClientRect();
|
||||
var width = node.offsetWidth == null ? clientRect.width : node.offsetWidth;
|
||||
return {
|
||||
top: clientRect.top,
|
||||
bottom: clientRect.bottom || (clientRect.top + clientRect.height),
|
||||
right: clientRect.left + width,
|
||||
left: clientRect.left,
|
||||
width: width,
|
||||
height: node.offsetHeight == null ? clientRect.height : node.offsetHeight
|
||||
};
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
exports.offsetBounds = function(node) {
|
||||
var parent = node.offsetParent ? exports.offsetBounds(node.offsetParent) : {top: 0, left: 0};
|
||||
|
||||
return {
|
||||
top: node.offsetTop + parent.top,
|
||||
bottom: node.offsetTop + node.offsetHeight + parent.top,
|
||||
right: node.offsetLeft + parent.left + node.offsetWidth,
|
||||
left: node.offsetLeft + parent.left,
|
||||
width: node.offsetWidth,
|
||||
height: node.offsetHeight
|
||||
};
|
||||
};
|
||||
|
||||
exports.parseBackgrounds = function(backgroundImage) {
|
||||
var whitespace = ' \r\n\t',
|
||||
method, definition, prefix, prefix_i, block, results = [],
|
||||
mode = 0, numParen = 0, quote, args;
|
||||
var appendResult = function() {
|
||||
if(method) {
|
||||
if (definition.substr(0, 1) === '"') {
|
||||
definition = definition.substr(1, definition.length - 2);
|
||||
}
|
||||
if (definition) {
|
||||
args.push(definition);
|
||||
}
|
||||
if (method.substr(0, 1) === '-' && (prefix_i = method.indexOf('-', 1 ) + 1) > 0) {
|
||||
prefix = method.substr(0, prefix_i);
|
||||
method = method.substr(prefix_i);
|
||||
}
|
||||
results.push({
|
||||
prefix: prefix,
|
||||
method: method.toLowerCase(),
|
||||
value: block,
|
||||
args: args,
|
||||
image: null
|
||||
});
|
||||
}
|
||||
args = [];
|
||||
method = prefix = definition = block = '';
|
||||
};
|
||||
args = [];
|
||||
method = prefix = definition = block = '';
|
||||
backgroundImage.split("").forEach(function(c) {
|
||||
if (mode === 0 && whitespace.indexOf(c) > -1) {
|
||||
return;
|
||||
}
|
||||
switch(c) {
|
||||
case '"':
|
||||
if(!quote) {
|
||||
quote = c;
|
||||
} else if(quote === c) {
|
||||
quote = null;
|
||||
}
|
||||
break;
|
||||
case '(':
|
||||
if(quote) {
|
||||
break;
|
||||
} else if(mode === 0) {
|
||||
mode = 1;
|
||||
block += c;
|
||||
return;
|
||||
} else {
|
||||
numParen++;
|
||||
}
|
||||
break;
|
||||
case ')':
|
||||
if (quote) {
|
||||
break;
|
||||
} else if(mode === 1) {
|
||||
if(numParen === 0) {
|
||||
mode = 0;
|
||||
block += c;
|
||||
appendResult();
|
||||
return;
|
||||
} else {
|
||||
numParen--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ',':
|
||||
if (quote) {
|
||||
break;
|
||||
} else if(mode === 0) {
|
||||
appendResult();
|
||||
return;
|
||||
} else if (mode === 1) {
|
||||
if (numParen === 0 && !method.match(/^url$/i)) {
|
||||
args.push(definition);
|
||||
definition = '';
|
||||
block += c;
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
block += c;
|
||||
if (mode === 0) {
|
||||
method += c;
|
||||
} else {
|
||||
definition += c;
|
||||
}
|
||||
});
|
||||
|
||||
appendResult();
|
||||
return results;
|
||||
};
|
@@ -1,6 +1,10 @@
|
||||
var GradientContainer = require('./gradientcontainer');
|
||||
|
||||
function WebkitGradientContainer(imageData) {
|
||||
GradientContainer.apply(this, arguments);
|
||||
this.type = (imageData.args[0] === "linear") ? this.TYPES.LINEAR : this.TYPES.RADIAL;
|
||||
}
|
||||
|
||||
WebkitGradientContainer.prototype = Object.create(GradientContainer.prototype);
|
||||
|
||||
module.exports = WebkitGradientContainer;
|
||||
|
@@ -1,3 +1,5 @@
|
||||
var Promise = require('./promise');
|
||||
|
||||
function XHR(url) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
@@ -18,3 +20,5 @@ function XHR(url) {
|
||||
xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = XHR;
|
||||
|
141
tests/cases/acid2.html
Normal file
141
tests/cases/acid2.html
Normal file
@@ -0,0 +1,141 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>The Second Acid Test</title>
|
||||
<style type="text/css">
|
||||
/* section numbers refer to CSS2.1 */
|
||||
|
||||
/* page setup */
|
||||
html { font: 12px sans-serif; margin: 0; padding: 0; overflow: hidden; /* hides scrollbars on viewport, see 11.1.1:3 */ background: white; color: red; }
|
||||
body { margin: 0; padding: 0; }
|
||||
|
||||
/* introduction message */
|
||||
.intro { font: 2em sans-serif; margin: 3.5em 2em; padding: 0.5em; border: solid thin; background: white; color: black; position: relative; z-index: 2; /* should cover the black and red bars that are fixed-positioned */ }
|
||||
.intro * { font: inherit; margin: 0; padding: 0; }
|
||||
.intro h1 { font-size: 1em; font-weight: bolder; margin: 0; padding: 0; }
|
||||
.intro :link { color: blue; }
|
||||
.intro :visited { color: purple; }
|
||||
|
||||
/* picture setup */
|
||||
#top { margin: 100em 3em 0; padding: 2em 0 0 .5em; text-align: left; font: 2em/24px sans-serif; color: navy; white-space: pre; } /* "Hello World!" text */
|
||||
.picture { position: relative; border: 1em solid transparent; margin: 0 0 100em 3em; } /* containing block for face */
|
||||
.picture { background: red; } /* overriden by preferred stylesheet below */
|
||||
|
||||
/* top line of face (scalp): fixed positioning and min/max height/width */
|
||||
.picture p { position: fixed; margin: 0; padding: 0; border: 0; top: 9em; left: 11em; width: 140%; max-width: 4em; height: 8px; min-height: 1em; max-height: 2mm; /* min-height overrides max-height, see 10.7 */ background: black; border-bottom: 0.5em yellow solid; }
|
||||
|
||||
/* bits that shouldn't be part of the top line (and shouldn't be visible at all): HTML parsing, "+" combinator, stacking order */
|
||||
.picture p.bad { border-bottom: red solid; /* shouldn't matter, because the "p + table + p" rule below should match it too, thus hiding it */ }
|
||||
.picture p + p { background: maroon; z-index: 1; } /* shouldn't match anything */
|
||||
.picture p + table + p { margin-top: 3em; /* should end up under the absolutely positioned table below, and thus not be visible */ }
|
||||
|
||||
/* second line of face: attribute selectors, float positioning */
|
||||
[class~=one].first.one { position: absolute; top: 0; margin: 36px 0 0 60px; padding: 0; border: black 2em; border-style: none solid; /* shrink wraps around float */ }
|
||||
[class~=one][class~=first] [class=second\ two][class="second two"] { float: right; width: 48px; height: 12px; background: yellow; margin: 0; padding: 0; } /* only content of abs pos block */
|
||||
|
||||
/* third line of face: width and overflow */
|
||||
.forehead { margin: 4em; width: 8em; border-left: solid black 1em; border-right: solid black 1em; background: red url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4%2F58BAAT%2FAf9jgNErAAAAAElFTkSuQmCC); /* that's a 1x1 yellow pixel PNG */ }
|
||||
.forehead * { width: 12em; line-height: 1em; }
|
||||
|
||||
/* class selectors headache */
|
||||
.two.error.two { background: maroon; } /* shouldn't match */
|
||||
.forehead.error.forehead { background: red; } /* shouldn't match */
|
||||
[class=second two] { background: red; } /* this should be ignored (invalid selector -- grammar says it only accepts IDENTs or STRINGs) */
|
||||
|
||||
/* fourth and fifth lines of face, with eyes: paint order test (see appendix E) and fixed backgrounds */
|
||||
/* the two images are identical: 2-by-2 squares with the top left
|
||||
and bottom right pixels set to yellow and the other two set to
|
||||
transparent. Since they are offset by one pixel from each other,
|
||||
the second one paints exactly over the transparent parts of the
|
||||
first one, thus creating a solid yellow block. */
|
||||
.eyes { position: absolute; top: 5em; left: 3em; margin: 0; padding: 0; background: red; }
|
||||
#eyes-a { height: 0; line-height: 2em; text-align: right; } /* contents should paint top-most because they're inline */
|
||||
#eyes-a object { display: inline; vertical-align: bottom; }
|
||||
#eyes-a object[type] { width: 7.5em; height: 2.5em; } /* should have no effect since that object should fallback to being inline (height/width don't apply to inlines) */
|
||||
#eyes-a object object object { border-right: solid 1em black; padding: 0 12px 0 11px; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAABnRSTlMAAAAAAABupgeRAAAABmJLR0QA%2FwD%2FAP%2BgvaeTAAAAEUlEQVR42mP4%2F58BCv7%2FZwAAHfAD%2FabwPj4AAAAASUVORK5CYII%3D) fixed 1px 0; }
|
||||
#eyes-b { float: left; width: 10em; height: 2em; background: fixed url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAABnRSTlMAAAAAAABupgeRAAAABmJLR0QA%2FwD%2FAP%2BgvaeTAAAAEUlEQVR42mP4%2F58BCv7%2FZwAAHfAD%2FabwPj4AAAAASUVORK5CYII%3D); border-left: solid 1em black; border-right: solid 1em red; } /* should paint in the middle layer because it is a float */
|
||||
#eyes-c { display: block; background: red; border-left: 2em solid yellow; width: 10em; height: 2em; } /* should paint bottom most because it is a block */
|
||||
|
||||
/* lines six to nine, with nose: auto margins */
|
||||
.nose { float: left; margin: -2em 2em -1em; border: solid 1em black; border-top: 0; min-height: 80%; height: 60%; max-height: 3em; /* percentages become auto (see 10.5 and 10.7) and intrinsic height is more than 3em, so 3em wins */ padding: 0; width: 12em; }
|
||||
.nose > div { padding: 1em 1em 3em; height: 0; background: yellow; }
|
||||
.nose div div { width: 2em; height: 2em; background: red; margin: auto; }
|
||||
.nose :hover div { border-color: blue; }
|
||||
.nose div:hover :before { border-bottom-color: inherit; }
|
||||
.nose div:hover :after { border-top-color: inherit; }
|
||||
.nose div div:before { display: block; border-style: none solid solid; border-color: red yellow black yellow; border-width: 1em; content: ''; height: 0; }
|
||||
.nose div :after { display: block; border-style: solid solid none; border-color: black yellow red yellow; border-width: 1em; content: ''; height: 0; }
|
||||
|
||||
/* between lines nine and ten: margin collapsing with 'float' and 'clear' */
|
||||
.empty { margin: 6.25em; height: 10%; /* computes to auto which makes it empty per 8.3.1:7 (own margins) */ }
|
||||
.empty div { margin: 0 2em -6em 4em; }
|
||||
.smile { margin: 5em 3em; clear: both; /* clearance is negative (see 8.3.1 and 9.5.1) */ }
|
||||
|
||||
/* line ten and eleven: containing block for abs pos */
|
||||
.smile div { margin-top: 0.25em; background: black; width: 12em; height: 2em; position: relative; bottom: -1em; }
|
||||
.smile div div { position: absolute; top: 0; right: 1em; width: auto; height: 0; margin: 0; border: yellow solid 1em; }
|
||||
|
||||
/* smile (over lines ten and eleven): backgrounds behind borders, inheritance of 'float', nested floats, negative heights */
|
||||
.smile div div span { display: inline; margin: -1em 0 0 0; border: solid 1em transparent; border-style: none solid; float: right; background: black; height: 1em; }
|
||||
.smile div div span em { float: inherit; border-top: solid yellow 1em; border-bottom: solid black 1em; } /* zero-height block; width comes from (zero-height) child. */
|
||||
.smile div div span em strong { width: 6em; display: block; margin-bottom: -1em; /* should have no effect, since parent has top&bottom borders, so this margin doesn't collapse */ }
|
||||
|
||||
/* line twelve: line-height */
|
||||
.chin { margin: -4em 4em 0; width: 8em; line-height: 1em; border-left: solid 1em black; border-right: solid 1em black; background: yellow url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAFSDNYfAAAAaklEQVR42u3XQQrAIAwAQeP%2F%2F6wf8CJBJTK9lnQ7FpHGaOurt1I34nfH9pMMZAZ8BwMGEvvh%2BBsJCAgICLwIOA8EBAQEBAQEBAQEBK79H5RfIQAAAAAAAAAAAAAAAAAAAAAAAAAAAID%2FABMSqAfj%2FsLmvAAAAABJRU5ErkJggg%3D%3D) /* 64x64 red square */ no-repeat fixed /* shouldn't be visible unless the smiley is moved to the top left of the viewport */; }
|
||||
.chin div { display: inline; font: 2px/4px serif; }
|
||||
|
||||
/* line thirteen: cascade and selector tests */
|
||||
.parser-container div { color: maroon; border: solid; color: orange; } /* setup */
|
||||
div.parser-container * { border-color: black; /* overrides (implied) border-color on previous line */ } /* setup */
|
||||
* div.parser { border-width: 0 2em; /* overrides (implied) declarations on earlier line */ } /* setup */
|
||||
|
||||
/* line thirteen continued: parser tests */
|
||||
.parser { /* comment parsing test -- comment ends before the end of this line, the backslash should have no effect: \*/ }
|
||||
.parser { margin: 0 5em 1em; padding: 0 1em; width: 2em; height: 1em; error: \}; background: yellow; } /* setup with parsing test */
|
||||
* html .parser { background: gray; }
|
||||
\.parser { padding: 2em; }
|
||||
.parser { m\argin: 2em; };
|
||||
.parser { height: 3em; }
|
||||
.parser { width: 200; }
|
||||
.parser { border: 5em solid red ! error; }
|
||||
.parser { background: red pink; }
|
||||
|
||||
/* line fourteen (last line of face): table */
|
||||
ul { display: table; padding: 0; margin: -1em 7em 0; background: red; }
|
||||
ul li { padding: 0; margin: 0; }
|
||||
ul li.first-part { display: table-cell; height: 1em; width: 1em; background: black; }
|
||||
ul li.second-part { display: table; height: 1em; width: 1em; background: black; } /* anonymous table cell wraps around this */
|
||||
ul li.third-part { display: table-cell; height: 0.5em; /* gets stretched to fit row */ width: 1em; background: black; }
|
||||
ul li.fourth-part { list-style: none; height: 1em; width: 1em; background: black; } /* anonymous table cell wraps around this */
|
||||
|
||||
/* bits that shouldn't appear: inline alignment in cells */
|
||||
.image-height-test { height: 10px; overflow: hidden; font: 20em serif; } /* only the area between the top of the line box and the top of the image should be visible */
|
||||
table { margin: 0; border-spacing: 0; }
|
||||
td { padding: 0; }
|
||||
|
||||
</style>
|
||||
<link rel="appendix stylesheet" href="data:text/css,.picture%20%7B%20background%3A%20none%3B%20%7D"> <!-- this stylesheet should be applied by default -->
|
||||
<script type="text/javascript" src="../test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div style="margin: 70px;"></div>
|
||||
<div class="picture">
|
||||
<p><table><tr><td></table><p class="bad"> <!-- <table> closes <p> per the HTML4 DTD -->
|
||||
<blockquote class="first one"><address class="second two"></address></blockquote>
|
||||
<div class="forehead"><div> </div></div>
|
||||
<div class="eyes"><div id="eyes-a"><object data="data:application/x-unknown,ERROR"><object data="http://www.damowmow.com/404/" type="text/html"><object data="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAAAYCAYAAAFy7sgCAAAGsUlEQVRo3u2ZbWwcZxHHf3s%2B7LNbO3ZjXBtowprGODRX0qpNQCjmJKuVKhMl1P2AkCwhFOIKkCBSm9IXavGFKAixIAECwkmWo5MrhRI3Ub40IEwQgp6aIDg3Cd6eEqyIHEteah%2B1E69vhw%2BZtTaX8704ZzkKjHS6271nZ56ZZ%2BY%2F%2F%2BdZKF%2FCwYshx3EkkggLsD1v4FQkEZZYLCbAKyG9%2Ba9EIsG6hnUAf8x74K3aUC3j4%2BM54HcsR2oAIomwZOezkv%2FnSHpYNh%2BNCmAE7xv94zvFdd1bHsjMZmQkPSxAJP%2B%2FfuBLwK54PC7JZFKAVJmzXLBt2w%2FMvcDLwIb8QS8CeJ4nkURYIomw7J%2FYJ8BvSiiXptGGxWds2%2Fa9%2Bnaxh%2BYAD%2Bgt04NDgABTpQY2cvvSFLzw86gWeBVwC8SzlOSv2YeBPfmDBoBHgKmR9LBEEmHZfDTqGykqfkUE0nA78BzQGfSgUeP3wNeTXwXg7MwZDhw4UHL6ra2ti79%2FOvljgG8AZ4H64Lhm4MvAocxsRppGG%2FxcXihlwLIs6R%2FfKV2HO%2F26uA94pdDYUKUZUU7W1RQYXA98Gnhaf5%2FXWX0HeAHYoQonqa4sZSOsSWMCWeC9Yko%2BCQwBe4E6oNc0Tc91XTl1%2BaTsn9gnI%2Blhyc5nZWxsrBIkKSbl2tiic3tW53YDEwOKaoFBrcOfqKee53lG9xsPMjV784r%2F4lO%2FpPvyJ9iyZcuvFSaXK5XYeAZ4CDgGvB3MS4B54LQuWYPeuy4iRFsevsXqpuYoqVQKIH2bK1CuDQNo11o4XUzh%2FcDWYIe1LEtyuZx4niee54njOGKapgfsqlL%2Bl2OjEXg8nxrc1dJ0h3hbtL%2BGCtz7KPBF4CuBe9uB15VafE8hr9qylI3HgG8C2%2FK7VyHZoJj7MrBRm30qFotJMpkU27YlHo%2F7Ha5a%2BV%2FKRkSJ4KuKRLVLKapTjB1SzAVIjY2NSXY%2BKyPpYdk%2FsU9OXT4pruv6BdZbBQfKsVGnvWlIe1VB6VQO8JxC1vZYLCbZ%2BaxsPhpdZDyRRFhG0sPiOE6ldKBg2lRg4xF1YCDIIIKN7DGgD3gH%2BBXwejKZfPrs2tPs%2FvPN2bKuYR1nd7xLKBSSJeqoXKnERjPwNWAG%2BLn2rZuM%2B4Tpml6vaWlp4eLcxVusZq5lCgVgOVKJjRqdX86ffL4D5wIoZACnTpw4wRMdT96i%2FImOJxERAs4uVyqxUacF%2FPdiCj%2BjdRBRGFtwXVdG0sPSdbhTmkYbpH98p2RmM2JZlig1vl0GWo4NQ%2Fn%2Bs5pKRXfwjweaxy7TND3HcRZbfC6X8xVPVQlGy7WxVWlO5XRXFXm6EZmrQuSXYyPE3SiVoEhE6Wyr0u2rumO6zv%2B21AFdQAswC1wCMuUCXCmyWQus103Qg8qlDO0lxwOb%2Fl4FiK3AB3VS%2FuKKLtK%2FgbeAnwG%2FvUODuRw%2FFrR0H1UC75fwu8oJ%2FhFsW5VIG%2FBUgEIN6Y65O4AHu4Ap0zQ9y7LEcZyb9lRBUHQcRyzL8unZVBW5bFWAvAp%2BhDQ2g4F47dUYtlU6obXA54DnVdFLekjUGGifh4AFy7LEdV3xj3X9I66m0QZpGm2QrsOd0j%2B%2BU0bSw5KZzYjrun6HWlAd961i4FfCj0aN1Usau%2Bc1lmuXPFwvAEumUut7tQQvAb%2FXb%2FT0bCAej9cODg7yt%2Bm%2F8q2%2F7OUHZ76PnZ1k2p0mJzlykmPancbOTnL0whHs7CQfb%2B5mx2d3sH79%2BtCRI0c6FeaOr9ICrIQfLvA%2B8BGNXxi4R6HrisJVUWrxAVW2oMFf0Aczim8o3kV6enowDIPjF9%2Fk%2BMU3S3rrjzMMg56eHr%2BxP7qKFbASfojG6kpeDGs1tiW53RxwWT%2Bin5q8w4xpQK5evQpAR30H7ZH2khNvj7TTUd8BgD4rqmu1ZKX8qNeY%2BfHz4zlXDgT5E8tpCTUq7XSBC4Euv8227TV9fX1E73%2BYtvo27BmbS9cvFVTY3bSRFza9yOcf6Gfmygy7d%2B%2Fm%2FPnzF4DvrsBLhnJlJfwIKXxv1PheAE4qK6p4H9AGbNKTuhngBPBPXYRe4IemaT5kWZbR19fHNbmGnZ1k4r3U4glDR30Hm5qjbGjsImJEOHbsGHv27JFz5869o0eFq01Jq%2BmHAXwI6FFKagMTgHM7GzFDS%2BoeLSMv7zjzC9x4Y7gxFovVDAwMEI1GaWlpWSzRVCrFwYMH%2FXfxZ4AfAa8B%2F7lDaGg1%2FQgp43lfK0yqtRMuJa3ceKe5DfgYsCYAZ2ngD8CfAkzqTpW7xY%2F%2FSznyX%2FVeUb2kVmX4AAAAAElFTkSuQmCC">ERROR</object></object></object></div><div id="eyes-b"></div><div id="eyes-c"></div></div> <!-- that's a PNG with 8bit alpha containing two eyes -->
|
||||
<div class="nose"><div><div></div></div></div>
|
||||
<div class="empty"><div></div></div>
|
||||
<div class="smile"><div><div><span><em><strong></strong></em></span></div></div></div>
|
||||
<div class="chin"><div> </div></div>
|
||||
<div class="parser-container"><div class="parser"><!-- ->ERROR<!- --></div></div> <!-- two dashes is what delimits a comment, so the text "->ERROR<!-" earlier on this line is actually part of a comment -->
|
||||
<ul>
|
||||
<li class="first-part"></li>
|
||||
<li class="second-part"></li>
|
||||
<li class="third-part"></li>
|
||||
<li class="fourth-part"></li>
|
||||
</ul>
|
||||
<div class="image-height-test"><table><tr><td><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAFSDNYfAAAAaklEQVR42u3XQQrAIAwAQeP%2F%2F6wf8CJBJTK9lnQ7FpHGaOurt1I34nfH9pMMZAZ8BwMGEvvh%2BBsJCAgICLwIOA8EBAQEBAQEBAQEBK79H5RfIQAAAAAAAAAAAAAAAAAAAAAAAAAAAID%2FABMSqAfj%2FsLmvAAAAABJRU5ErkJggg%3D%3D" alt=""></td></tr></table></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@@ -112,6 +112,10 @@
|
||||
.linearGradient8 {
|
||||
background: linear-gradient(to top left, #fff 0%, #00263c 100%);
|
||||
}
|
||||
|
||||
.linearGradient9 {
|
||||
background: linear-gradient(to top left, white 0%, black 100%);
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
@@ -125,6 +129,7 @@
|
||||
<div class="linearGradient6"> </div>
|
||||
<div class="linearGradient7"> </div>
|
||||
<div class="linearGradient8"> </div>
|
||||
<div class="linearGradient9"> </div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -29,7 +29,7 @@
|
||||
.container {
|
||||
float: left;
|
||||
border: 1px solid black;
|
||||
width: 200px;
|
||||
width: 150px;
|
||||
height: 200px;
|
||||
background-image: url(../../assets/image.jpg);
|
||||
background-size: 34px;
|
||||
@@ -42,7 +42,7 @@
|
||||
<div class="container"></div>
|
||||
<div class="container" style="background-repeat: repeat-y"></div>
|
||||
<div class="container" style="background-repeat: repeat-x"></div>
|
||||
|
||||
<div class="container" style="background-size: 150% auto"></div>
|
||||
<div class="horizontal">
|
||||
<div style='background-size: cover;'></div>
|
||||
<div style='background-size: contain;'></div>
|
||||
|
@@ -57,6 +57,12 @@
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
.box6 {
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
border-radius: 200px;
|
||||
}
|
||||
|
||||
html {
|
||||
background: #3a84c3;
|
||||
}
|
||||
@@ -69,5 +75,6 @@
|
||||
<div class="box3"> </div>
|
||||
<div class="box4"> </div>
|
||||
<div class="box5"> </div>
|
||||
<div class="box6"> </div>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -1,144 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Mocha Tests</title>
|
||||
<link rel="stylesheet" href="lib/mocha.css" />
|
||||
<script type="text/javascript" src="../../src/color.js"></script>
|
||||
<script src="lib/expect.js"></script>
|
||||
<script src="lib/mocha.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<script>
|
||||
describe("Colors", function() {
|
||||
describe("named colors", function() {
|
||||
it("bisque", function () {
|
||||
var c = new Color("bisque");
|
||||
assertColor(c, 255, 228, 196, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("BLUE", function () {
|
||||
var c = new Color("BLUE");
|
||||
assertColor(c, 0, 0, 255, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("rgb()", function() {
|
||||
it("rgb(1,3,5)", function () {
|
||||
var c = new Color("rgb(1,3,5)");
|
||||
assertColor(c, 1, 3, 5, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("rgb(222, 111, 50)", function () {
|
||||
var c = new Color("rgb(222, 111, 50)");
|
||||
assertColor(c, 222, 111, 50, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("rgb( 222, 111 , 50)", function () {
|
||||
var c = new Color("rgb(222 , 111 , 50)");
|
||||
assertColor(c, 222, 111, 50, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("rgba()", function() {
|
||||
it("rgba(200,3,5,1)", function () {
|
||||
var c = new Color("rgba(200,3,5,1)");
|
||||
assertColor(c, 200, 3, 5, 1);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("rgba(222, 111, 50, 0.22)", function () {
|
||||
var c = new Color("rgba(222, 111, 50, 0.22)");
|
||||
assertColor(c, 222, 111, 50, 0.22);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("rgba( 222, 111 , 50, 0.123 )", function () {
|
||||
var c = new Color("rgba(222 , 111 , 50, 0.123)");
|
||||
assertColor(c, 222, 111, 50, 0.123);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("hex", function() {
|
||||
it("#7FFFD4", function () {
|
||||
var c = new Color("#7FFFD4");
|
||||
assertColor(c, 127, 255, 212, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("#f0ffff", function () {
|
||||
var c = new Color("#f0ffff");
|
||||
assertColor(c, 240, 255, 255, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("#fff", function () {
|
||||
var c = new Color("#fff");
|
||||
assertColor(c, 255, 255, 255, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("from array", function() {
|
||||
it("[1,2,3]", function () {
|
||||
var c = new Color([1,2,3]);
|
||||
assertColor(c, 1, 2, 3, null);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("[5,6,7,1]", function () {
|
||||
var c = new Color([5,6,7, 1]);
|
||||
assertColor(c, 5, 6, 7, 1);
|
||||
expect(c.isTransparent()).to.equal(false);
|
||||
});
|
||||
|
||||
it("[5,6,7,0]", function () {
|
||||
var c = new Color([5,6,7, 0]);
|
||||
assertColor(c, 5, 6, 7, 0);
|
||||
expect(c.isTransparent()).to.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("transparency", function() {
|
||||
it("transparent", function () {
|
||||
var c = new Color("transparent");
|
||||
assertColor(c, 0, 0, 0, 0);
|
||||
expect(c.isTransparent()).to.equal(true);
|
||||
});
|
||||
|
||||
it("rgba(255,255,255,0)", function () {
|
||||
var c = new Color("rgba(255,255,255,0)");
|
||||
assertColor(c, 255, 255, 255, 0);
|
||||
expect(c.isTransparent()).to.equal(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function assertColor(c, r, g, b, a) {
|
||||
expect(c.r).to.equal(r);
|
||||
expect(c.g).to.equal(g);
|
||||
expect(c.b).to.equal(b);
|
||||
expect(c.a).to.equal(a);
|
||||
}
|
||||
|
||||
mocha.checkLeaks();
|
||||
mocha.globals(['jQuery']);
|
||||
if (window.mochaPhantomJS) {
|
||||
mochaPhantomJS.run();
|
||||
}
|
||||
else {
|
||||
mocha.run();
|
||||
}
|
||||
mocha.suite.afterAll(function() {
|
||||
document.body.setAttribute('data-complete', 'true');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@@ -1,3 +1,5 @@
|
||||
var NodeContainer = html2canvas.NodeContainer;
|
||||
|
||||
describe('Borders', function() {
|
||||
$('#borders div').each(function(i, node) {
|
||||
it($(this).attr('style'), function() {
|
||||
@@ -41,7 +43,7 @@ describe('Background-position', function() {
|
||||
|
||||
var container = new NodeContainer(node, null);
|
||||
var item = container.css(prop),
|
||||
backgroundPosition = container.parseBackgroundPosition(getBounds(node), img),
|
||||
backgroundPosition = container.parseBackgroundPosition(html2canvas.utils.getBounds(node), img),
|
||||
split = (window.getComputedStyle) ? $(node).css(prop).split(" ") : [$(node).css(prop+"X"), $(node).css(prop+"Y")];
|
||||
|
||||
var testEl = $('<div />').css({
|
||||
@@ -65,26 +67,28 @@ describe('Text-shadow', function() {
|
||||
var index = i + 1;
|
||||
var container = new NodeContainer(node, null);
|
||||
var shadows = container.parseTextShadows();
|
||||
if (i === 0) {
|
||||
expect(shadows.length).to.equal(0);
|
||||
} else {
|
||||
expect(shadows.length).to.equal(i >= 6 ? 2 : 1);
|
||||
expect(shadows[0].offsetX).to.equal(i);
|
||||
expect(shadows[0].offsetY).to.equal(i);
|
||||
if (i < 2) {
|
||||
expect(shadows[0].color.toString()).to.equal('rgba(0,0,0,0)');
|
||||
} else if (i % 2 === 0) {
|
||||
expect(shadows[0].color.toString()).to.equal('rgb(2,2,2)');
|
||||
it(node.style.textShadow, function() {
|
||||
if (i === 0) {
|
||||
expect(shadows.length).to.equal(0);
|
||||
} else {
|
||||
var opacity = '0.2';
|
||||
expect(shadows[0].color.toString()).to.match(/rgba\(2,2,2,(0.2|0\.199219)\)/);
|
||||
}
|
||||
expect(shadows.length).to.equal(i >= 6 ? 2 : 1);
|
||||
expect(shadows[0].offsetX).to.equal(i);
|
||||
expect(shadows[0].offsetY).to.equal(i);
|
||||
if (i < 2) {
|
||||
expect(shadows[0].color.toString()).to.equal('rgba(0,0,0,0)');
|
||||
} else if (i % 2 === 0) {
|
||||
expect(shadows[0].color.toString()).to.equal('rgb(2,2,2)');
|
||||
} else {
|
||||
var opacity = '0.2';
|
||||
expect(shadows[0].color.toString()).to.match(/rgba\(2,2,2,(0.2|0\.199219)\)/);
|
||||
}
|
||||
|
||||
// only testing blur once
|
||||
if (i === 1) {
|
||||
expect(shadows[0].blur).to.equal('1');
|
||||
// only testing blur once
|
||||
if (i === 1) {
|
||||
expect(shadows[0].blur).to.equal('1');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -210,7 +214,7 @@ describe('Background-image', function() {
|
||||
|
||||
function test_parse_background_image(value, expected, name) {
|
||||
it(name, function() {
|
||||
expect(parseBackgrounds(value)).to.eql(Array.isArray(expected) ? expected : [expected]);
|
||||
expect(html2canvas.utils.parseBackgrounds(value)).to.eql(Array.isArray(expected) ? expected : [expected]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@@ -4,9 +4,6 @@
|
||||
<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>
|
||||
@@ -44,6 +41,8 @@
|
||||
|
||||
<div id="green-block"></div>
|
||||
<script>
|
||||
var CanvasRenderer = html2canvas.CanvasRenderer;
|
||||
|
||||
describe("Rendering input values", function() {
|
||||
it("uses default value for input[type='text']", function(done) {
|
||||
CanvasRenderer.prototype.text = function(text) {
|
||||
@@ -109,7 +108,7 @@
|
||||
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) {
|
||||
html2canvas(document.querySelector("#block4"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
done();
|
||||
@@ -139,7 +138,7 @@
|
||||
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) {
|
||||
html2canvas(document.querySelector("#block5"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
done();
|
||||
|
@@ -35,6 +35,15 @@ describe("Gradients", function() {
|
||||
" to(rgb(191, 110, 78))"
|
||||
]
|
||||
},
|
||||
{
|
||||
method: 'linear-gradient',
|
||||
args: [
|
||||
"0deg",
|
||||
" rgb(221, 221, 221)",
|
||||
" rgb(221, 221, 221) 50%",
|
||||
" transparent 50%"
|
||||
]
|
||||
},
|
||||
{
|
||||
method: "radial-gradient",
|
||||
args: [
|
||||
@@ -97,11 +106,11 @@ describe("Gradients", function() {
|
||||
}
|
||||
];
|
||||
|
||||
$('#backgroundGradients div').each(function(i, node) {
|
||||
var container = new NodeContainer(node, null);
|
||||
[].slice.call(document.querySelectorAll('#backgroundGradients div'), 0).forEach(function(node, i) {
|
||||
var container = new html2canvas.NodeContainer(node, null);
|
||||
var value = container.css("backgroundImage");
|
||||
it(value, function() {
|
||||
var parsedBackground = parseBackgrounds(value);
|
||||
var parsedBackground = html2canvas.utils.parseBackgrounds(value);
|
||||
if (parsedBackground[0].args[0] === "0% 50%") {
|
||||
parsedBackground[0].args[0] = 'left';
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@
|
||||
<div id="green-block"></div>
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<script>
|
||||
var Promise = html2canvas.Promise;
|
||||
describe("Multiple renders", function() {
|
||||
it("render correctly", function(done) {
|
||||
this.timeout(10000);
|
||||
|
@@ -23,6 +23,7 @@
|
||||
<div style="background: red; width: 200px; height:200px;" id="block"></div>
|
||||
<div style="width: 200px; height:200px;" id="block2"></div>
|
||||
<script>
|
||||
var Promise = html2canvas.Promise;
|
||||
describe("options.onclone", function() {
|
||||
it("with a function", function(done) {
|
||||
html2canvas(document.querySelector("#block"), {onclone: function(document) {
|
||||
|
@@ -3,23 +3,7 @@
|
||||
<meta charset="utf-8">
|
||||
<title>Mocha Tests</title>
|
||||
<link rel="stylesheet" href="lib/mocha.css" />
|
||||
<script type="text/javascript" src="../../src/log.js"></script>
|
||||
<script type="text/javascript" src="../../src/color.js"></script>
|
||||
<script type="text/javascript" src="../../src/nodecontainer.js"></script>
|
||||
<script type="text/javascript" src="../../src/stackingcontext.js"></script>
|
||||
<script type="text/javascript" src="../../src/textcontainer.js"></script>
|
||||
<script type="text/javascript" src="../../src/support.js"></script>
|
||||
<script type="text/javascript" src="../../src/imagecontainer.js"></script>
|
||||
<script type="text/javascript" src="../../src/gradientcontainer.js"></script>
|
||||
<script type="text/javascript" src="../../src/lineargradientcontainer.js"></script>
|
||||
<script type="text/javascript" src="../../src/webkitgradientcontainer.js"></script>
|
||||
<script type="text/javascript" src="../../src/imageloader.js"></script>
|
||||
<script type="text/javascript" src="../../src/nodeparser.js"></script>
|
||||
<script type="text/javascript" src="../../src/font.js"></script>
|
||||
<script type="text/javascript" src="../../src/fontmetrics.js"></script>
|
||||
<script type="text/javascript" src="../../src/renderer.js"></script>
|
||||
<script type="text/javascript" src="../../src/promise.js"></script>
|
||||
<script type="text/javascript" src="../../src/renderers/canvas.js"></script>
|
||||
<script src="../../dist/html2canvas.js"></script>
|
||||
<script src="../assets/jquery-1.6.2.js"></script>
|
||||
<script src="lib/expect.js"></script>
|
||||
<script src="lib/mocha.js"></script>
|
||||
@@ -124,6 +108,12 @@
|
||||
/* W3C */
|
||||
background: linear-gradient(top, #f0b7a1 0%, #8c3310 50%, #752201 51%, #bf6e4e 100%);
|
||||
}
|
||||
|
||||
.linearGradient4 {
|
||||
background: -webkit-linear-gradient(0deg, #ddd, #ddd 50%, transparent 50%);
|
||||
background: linear-gradient(0deg, #ddd, #ddd 50%, transparent 50%);
|
||||
}
|
||||
|
||||
.radialGradient {
|
||||
background: -moz-radial-gradient(75% 19%, ellipse closest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(75% 19%, ellipse closest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
@@ -172,6 +162,7 @@
|
||||
<div class="linearGradientSimple"></div>
|
||||
<div class="linearGradientWithStops"></div>
|
||||
<div class="linearGradient3"></div>
|
||||
<div class="linearGradient4"></div>
|
||||
<div class="radialGradient"></div>
|
||||
<div class="radialGradient2"></div>
|
||||
<div class="radialGradient3"></div>
|
||||
|
@@ -12,6 +12,12 @@
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<div id="scroll-render" style="height: 200px; width: 200px;">
|
||||
<div style="height: 500px; width: 400px;overflow: scroll;" id="scrollable">
|
||||
<div style="height: 500px;background: red;"></div>
|
||||
<div style="height: 650px; background: green"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 2200px;"></div>
|
||||
<div style="height: 500px;background: green;"><a name="content">content</a></div>
|
||||
<script>
|
||||
@@ -32,7 +38,7 @@
|
||||
window.location.hash = "#content";
|
||||
setTimeout(function() {
|
||||
var top = $(window).scrollTop();
|
||||
html2canvas(document.body, {type: 'view', removeContainer: false}).then(function () {
|
||||
html2canvas(document.body, {type: 'view'}).then(function () {
|
||||
var currentTop = $(window).scrollTop();
|
||||
window.location.hash = "";
|
||||
expect(currentTop).to.be.greaterThan(1500);
|
||||
@@ -45,8 +51,35 @@
|
||||
});
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it("with content scroll", function (done) {
|
||||
$("#scrollable").scrollTop(500);
|
||||
setTimeout(function() {
|
||||
html2canvas(document.querySelector("#scroll-render")).then(function (canvas) {
|
||||
expect($("#scrollable").scrollTop()).to.equal(500);
|
||||
document.body.appendChild(canvas);
|
||||
expect(canvas.width).to.equal(200);
|
||||
expect(canvas.height).to.equal(200);
|
||||
validCanvasPixels(canvas);
|
||||
done();
|
||||
}).catch(function (error) {
|
||||
done(error);
|
||||
});
|
||||
}, 0);
|
||||
});
|
||||
});
|
||||
|
||||
function validCanvasPixels(canvas) {
|
||||
var ctx = canvas.getContext("2d");
|
||||
var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
|
||||
for (var i = 0, len = 200*199*4; i < len; i+=4) {
|
||||
if (data[i] !== 0 || data[i+1] !== 128 || data[i+2] !== 0 || data[i+3] !== 255) {
|
||||
console.log(i, data[i], data[i+1], data[i+2], data[i+3]);
|
||||
expect().fail("Invalid canvas data");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
after(function() {
|
||||
if (history) {
|
||||
history.pushState("", document.title, window.location.pathname + window.location.search);
|
||||
|
119
tests/node/color.js
Normal file
119
tests/node/color.js
Normal file
@@ -0,0 +1,119 @@
|
||||
var Color = require('../../src/color');
|
||||
var assert = require('assert');
|
||||
|
||||
describe("Colors", function() {
|
||||
describe("named colors", function() {
|
||||
it("bisque", function () {
|
||||
var c = new Color("bisque");
|
||||
assertColor(c, 255, 228, 196, null);
|
||||
assert.equal(c.isTransparent(), false);
|
||||
});
|
||||
|
||||
it("BLUE", function () {
|
||||
var c = new Color("BLUE");
|
||||
assertColor(c, 0, 0, 255, null);
|
||||
assert.equal(c.isTransparent(), false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("rgb()", function() {
|
||||
it("rgb(1,3,5)", function () {
|
||||
var c = new Color("rgb(1,3,5)");
|
||||
assertColor(c, 1, 3, 5, null);
|
||||
assert.equal(c.isTransparent(), false);
|
||||
});
|
||||
|
||||
it("rgb(222, 111, 50)", function () {
|
||||
var c = new Color("rgb(222, 111, 50)");
|
||||
assertColor(c, 222, 111, 50, null);
|
||||
assert.equal(c.isTransparent(), false);
|
||||
});
|
||||
|
||||
it("rgb( 222, 111 , 50)", function () {
|
||||
var c = new Color("rgb(222 , 111 , 50)");
|
||||
assertColor(c, 222, 111, 50, null);
|
||||
assert.equal(c.isTransparent(), false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("rgba()", function() {
|
||||
it("rgba(200,3,5,1)", function () {
|
||||
var c = new Color("rgba(200,3,5,1)");
|
||||
assertColor(c, 200, 3, 5, 1);
|
||||
assert.equal(c.isTransparent(), false);
|
||||
});
|
||||
|
||||
it("rgba(222, 111, 50, 0.22)", function () {
|
||||
var c = new Color("rgba(222, 111, 50, 0.22)");
|
||||
assertColor(c, 222, 111, 50, 0.22);
|
||||
assert.equal(c.isTransparent(), false);
|
||||
});
|
||||
|
||||
it("rgba( 222, 111 , 50, 0.123 )", function () {
|
||||
var c = new Color("rgba(222 , 111 , 50, 0.123)");
|
||||
assertColor(c, 222, 111, 50, 0.123);
|
||||
assert.equal(c.isTransparent(), false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("hex", function() {
|
||||
it("#7FFFD4", function () {
|
||||
var c = new Color("#7FFFD4");
|
||||
assertColor(c, 127, 255, 212, null);
|
||||
assert.equal(c.isTransparent(), false);
|
||||
});
|
||||
|
||||
it("#f0ffff", function () {
|
||||
var c = new Color("#f0ffff");
|
||||
assertColor(c, 240, 255, 255, null);
|
||||
assert.equal(c.isTransparent(), false);
|
||||
});
|
||||
|
||||
it("#fff", function () {
|
||||
var c = new Color("#fff");
|
||||
assertColor(c, 255, 255, 255, null);
|
||||
assert.equal(c.isTransparent(), false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("from array", function() {
|
||||
it("[1,2,3]", function () {
|
||||
var c = new Color([1,2,3]);
|
||||
assertColor(c, 1, 2, 3, null);
|
||||
assert.equal(c.isTransparent(), false);
|
||||
});
|
||||
|
||||
it("[5,6,7,1]", function () {
|
||||
var c = new Color([5,6,7, 1]);
|
||||
assertColor(c, 5, 6, 7, 1);
|
||||
assert.equal(c.isTransparent(), false);
|
||||
});
|
||||
|
||||
it("[5,6,7,0]", function () {
|
||||
var c = new Color([5,6,7, 0]);
|
||||
assertColor(c, 5, 6, 7, 0);
|
||||
assert.equal(c.isTransparent(), true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("transparency", function() {
|
||||
it("transparent", function () {
|
||||
var c = new Color("transparent");
|
||||
assertColor(c, 0, 0, 0, 0);
|
||||
assert.equal(c.isTransparent(), true);
|
||||
});
|
||||
|
||||
it("rgba(255,255,255,0)", function () {
|
||||
var c = new Color("rgba(255,255,255,0)");
|
||||
assertColor(c, 255, 255, 255, 0);
|
||||
assert.equal(c.isTransparent(), true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function assertColor(c, r, g, b, a) {
|
||||
assert.equal(c.r, r);
|
||||
assert.equal(c.g, g);
|
||||
assert.equal(c.b, b);
|
||||
assert.equal(c.a, a);
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
var assert = require('assert');
|
||||
var path = require('path');
|
||||
var html2canvas = require('../../');
|
||||
|
||||
describe("Package", function() {
|
||||
@@ -6,3 +7,18 @@ describe("Package", function() {
|
||||
assert.equal(typeof(html2canvas), "function");
|
||||
});
|
||||
});
|
||||
|
||||
describe.only("requirejs", function() {
|
||||
var requirejs = require('requirejs');
|
||||
|
||||
requirejs.config({
|
||||
baseUrl: path.resolve(__dirname, '../../dist')
|
||||
});
|
||||
|
||||
it("should have html2canvas defined", function(done) {
|
||||
requirejs(['html2canvas'], function(h2c) {
|
||||
assert.equal(typeof(h2c), "function");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,10 +1,3 @@
|
||||
/*
|
||||
html2canvas @VERSION@ <http://html2canvas.hertzen.com>
|
||||
Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
http://www.twitter.com/niklasvh
|
||||
|
||||
Released under MIT License
|
||||
*/
|
||||
var h2cSelector, h2cOptions;
|
||||
(function(document, window) {
|
||||
function appendScript(src) {
|
||||
@@ -14,7 +7,7 @@ var h2cSelector, h2cOptions;
|
||||
var sources = ['log', 'punycode/punycode', 'core', 'nodecontainer', 'pseudoelementcontainer', 'stackingcontext', 'textcontainer', 'support', 'imagecontainer', 'dummyimagecontainer', 'proxyimagecontainer', 'gradientcontainer',
|
||||
'lineargradientcontainer', 'webkitgradientcontainer', 'svgcontainer', 'svgnodecontainer', 'imageloader', 'nodeparser', 'font', 'fontmetrics', 'renderer', 'promise', 'xhr', 'framecontainer', 'proxy', 'color', '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', '/dist/html2canvas'].forEach(appendScript);
|
||||
|
||||
if (typeof(noFabric) === "undefined") {
|
||||
appendScript('/dist/html2canvas.svg');
|
||||
@@ -104,7 +97,7 @@ var h2cSelector, h2cOptions;
|
||||
textDecoration:'none',
|
||||
display:'none'
|
||||
}).appendTo(document.body).fadeIn();
|
||||
log(msg);
|
||||
console.log(msg);
|
||||
}
|
||||
};
|
||||
})(jQuery);
|
||||
|
Reference in New Issue
Block a user