Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
45ad98e73c |
19
.gitignore
vendored
@ -2,19 +2,8 @@
|
||||
/images/
|
||||
/tests/templates/
|
||||
/tests/cache/
|
||||
/tests/flashcanvas.html
|
||||
/lib/
|
||||
/bin/
|
||||
/dist/
|
||||
/build/tmp.js
|
||||
index.html
|
||||
image.jpg
|
||||
/.project
|
||||
/.settings/
|
||||
/tests/certificate.pem
|
||||
node_modules/
|
||||
.envrc
|
||||
server.js
|
||||
*.sublime-workspace
|
||||
chromedriver.log
|
||||
*.baseline
|
||||
*.iml
|
||||
.idea/
|
||||
.DS_Store
|
||||
screenshots_local.html
|
12
.travis.yml
@ -1,12 +0,0 @@
|
||||
---
|
||||
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="
|
||||
before_script:
|
||||
- npm install -g grunt-cli
|
||||
- curl https://gist.github.com/niklasvh/6150144/raw/sauce_connect_setup.sh | bash
|
99
Gruntfile.js
@ -1,99 +0,0 @@
|
||||
/*global module:false*/
|
||||
module.exports = function(grunt) {
|
||||
|
||||
var meta = {
|
||||
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, undefined){\n\n',
|
||||
post: '\n})(window,document);'
|
||||
};
|
||||
|
||||
// Project configuration.
|
||||
grunt.initConfig({
|
||||
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
|
||||
qunit: {
|
||||
files: ['tests/qunit/index.html']
|
||||
},
|
||||
concat: {
|
||||
dist: {
|
||||
src: [
|
||||
'src/Core.js',
|
||||
'src/Font.js',
|
||||
'src/Generate.js',
|
||||
'src/Queue.js',
|
||||
'src/Parse.js',
|
||||
'src/Preload.js',
|
||||
'src/Renderer.js',
|
||||
'src/Support.js',
|
||||
'src/Util.js',
|
||||
'src/renderers/Canvas.js'
|
||||
],
|
||||
dest: 'build/<%= pkg.name %>.js'
|
||||
},
|
||||
options:{
|
||||
banner: meta.banner + meta.pre,
|
||||
footer: meta.post
|
||||
}
|
||||
},
|
||||
uglify: {
|
||||
dist: {
|
||||
src: ['<%= concat.dist.dest %>'],
|
||||
dest: 'build/<%= pkg.name %>.min.js'
|
||||
},
|
||||
options: {
|
||||
banner: meta.banner
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
files: 'src/*',
|
||||
tasks: ['build', 'jshint']
|
||||
},
|
||||
jshint: {
|
||||
all: ['<%= concat.dist.dest %>'],
|
||||
options: {
|
||||
curly: true,
|
||||
eqeqeq: true,
|
||||
immed: true,
|
||||
latedef: true,
|
||||
newcap: true,
|
||||
noarg: true,
|
||||
sub: true,
|
||||
undef: true,
|
||||
boss: true,
|
||||
eqnull: true,
|
||||
browser: true,
|
||||
globals: {
|
||||
jQuery: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
grunt.registerTask('webdriver', 'Browser render tests', function(arg1) {
|
||||
var selenium = require("./tests/selenium.js");
|
||||
var done = this.async();
|
||||
|
||||
if (arguments.length) {
|
||||
selenium[arg1].apply(null, arguments);
|
||||
} else {
|
||||
selenium.tests();
|
||||
}
|
||||
});
|
||||
|
||||
// Load tasks
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-qunit');
|
||||
|
||||
// Default task.
|
||||
grunt.registerTask('build', ['concat', 'uglify']);
|
||||
grunt.registerTask('default', ['concat', 'jshint', 'qunit', 'uglify']);
|
||||
grunt.registerTask('travis', ['concat', 'jshint', 'qunit', 'uglify', 'webdriver']);
|
||||
|
||||
};
|
37
LICENSE
@ -1,22 +1,21 @@
|
||||
Copyright (c) 2012 Niklas von Hertzen
|
||||
/*
|
||||
* The MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
10
bower.json
@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "html2canvas",
|
||||
"version": "0.4.1",
|
||||
"description": "Screenshots with JavaScript",
|
||||
"main": "build/html2canvas.js",
|
||||
"ignore": [
|
||||
"tests",
|
||||
".travis.yml"
|
||||
]
|
||||
}
|
83
build.xml
Normal file
@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<project name="html2canvas" basedir=".">
|
||||
<property name="src.dir" location="src"/>
|
||||
<property name="lib.dir" location="lib"/>
|
||||
<property name="build.dir" location="build"/>
|
||||
<property name="dist" location="dist"/>
|
||||
|
||||
|
||||
<property name="jquery-externs" value="jquery-1.4.4.externs.js"/>
|
||||
|
||||
|
||||
<property name="JS_NAME" value="html2canvas.js"/>
|
||||
<property name="JS_NAME_MIN" value="html2canvas.min.js"/>
|
||||
<property name="JQUERY_PLUGIN_NAME" value="jquery.plugin.html2canvas.js"/>
|
||||
|
||||
|
||||
<path id="sourcefiles">
|
||||
<fileset dir="${src.dir}" includes="LICENSE"/>
|
||||
<fileset dir="." includes="LICENSE"/>
|
||||
<fileset dir="${src.dir}" includes="Core.js"/>
|
||||
<fileset dir="${src.dir}" includes="Background.js"/>
|
||||
<fileset dir="${src.dir}" includes="Border.js"/>
|
||||
<fileset dir="${src.dir}" includes="Draw.js"/>
|
||||
<fileset dir="${src.dir}" includes="Forms.js"/>
|
||||
<fileset dir="${src.dir}" includes="Images.js"/>
|
||||
<fileset dir="${src.dir}" includes="Parse.js"/>
|
||||
<fileset dir="${src.dir}" includes="Preload.js"/>
|
||||
<fileset dir="${src.dir}" includes="Queue.js"/>
|
||||
<fileset dir="${src.dir}" includes="Renderer.js"/>
|
||||
<fileset dir="${src.dir}" includes="Lists.js"/>
|
||||
<fileset dir="${src.dir}" includes="Text.js"/>
|
||||
<fileset dir="${src.dir}" includes="Traversing.js"/>
|
||||
<fileset dir="${src.dir}" includes="Util.js"/>
|
||||
</path>
|
||||
|
||||
<path id="jquery-plugin">
|
||||
<fileset dir="${src.dir}" includes="LICENSE"/>
|
||||
<fileset dir="." includes="LICENSE"/>
|
||||
<fileset dir="${src.dir}/plugins" includes="${JQUERY_PLUGIN_NAME}"/>
|
||||
</path>
|
||||
|
||||
<path id="minified">
|
||||
<fileset dir="${src.dir}" includes="LICENSE"/>
|
||||
<fileset dir="${build.dir}" includes="tmp.js"/>
|
||||
</path>
|
||||
|
||||
<target name="plugins">
|
||||
<concat fixlastline="yes" destfile="${build.dir}/${JQUERY_PLUGIN_NAME}">
|
||||
<path refid="jquery-plugin"/>
|
||||
</concat>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="source">
|
||||
<concat fixlastline="yes" destfile="${build.dir}/${JS_NAME}">
|
||||
<path refid="sourcefiles"/>
|
||||
</concat>
|
||||
</target>
|
||||
|
||||
|
||||
<taskdef name="jscomp" classname="com.google.javascript.jscomp.ant.CompileTask"
|
||||
classpath="${lib.dir}/compiler.jar"/>
|
||||
|
||||
<target name="release">
|
||||
|
||||
<jscomp compilationLevel="simple" warning="verbose"
|
||||
debug="false"
|
||||
output="${build.dir}/tmp.js">
|
||||
<externs dir="${lib.dir}">
|
||||
<file name="${jquery-externs}"/>
|
||||
</externs>
|
||||
<sources dir="${build.dir}">
|
||||
<file name="${JS_NAME}" />
|
||||
</sources>
|
||||
</jscomp>
|
||||
|
||||
<concat fixlastline="yes" destfile="${build.dir}/${JS_NAME_MIN}">
|
||||
<path refid="minified"/>
|
||||
</concat>
|
||||
|
||||
</target>
|
||||
</project>
|
||||
|
4849
build/html2canvas.js
61
build/html2canvas.min.js
vendored
118
build/jquery.plugin.html2canvas.js
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* html2canvas v0.25 <http://html2canvas.hertzen.com>
|
||||
* Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
* http://www.twitter.com/niklasvh
|
||||
*
|
||||
* Released under MIT License
|
||||
*/
|
||||
|
||||
/*
|
||||
* The MIT License
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* jQuery helper plugin for examples and tests
|
||||
*/
|
||||
|
||||
(function( $ ){
|
||||
$.fn.html2canvas = function(options) {
|
||||
|
||||
var date = new Date();
|
||||
var message,
|
||||
timeoutTimer,
|
||||
timer = date.getTime();
|
||||
|
||||
var object = $.extend({},{
|
||||
logging: false,
|
||||
proxyUrl: "http://html2canvas.appspot.com/", // running html2canvas-python proxy
|
||||
ready: function(renderer) {
|
||||
|
||||
var finishTime = new Date();
|
||||
// console.log((finishTime.getTime()-timer)/1000);
|
||||
|
||||
|
||||
document.body.appendChild(renderer.canvas);
|
||||
|
||||
|
||||
|
||||
var canvas = $(renderer.canvas);
|
||||
canvas.css('position','absolute')
|
||||
.css('left',0).css('top',0);
|
||||
|
||||
|
||||
|
||||
// $('body').append(canvas);
|
||||
$(canvas).siblings().toggle();
|
||||
|
||||
throwMessage('Screenshot created in '+ ((finishTime.getTime()-timer)/1000) + " seconds<br />Total of "+renderer.numDraws+" draws performed",4000);
|
||||
|
||||
|
||||
$(window).click(function(){
|
||||
if (!canvas.is(':visible')){
|
||||
$(canvas).toggle().siblings().toggle();
|
||||
throwMessage("Canvas Render visible");
|
||||
} else{
|
||||
$(canvas).siblings().toggle();
|
||||
$(canvas).toggle();
|
||||
throwMessage("Canvas Render hidden");
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
},options)
|
||||
|
||||
new html2canvas(this.get(0), object);
|
||||
|
||||
|
||||
function throwMessage(msg,duration){
|
||||
|
||||
window.clearTimeout(timeoutTimer);
|
||||
timeoutTimer = window.setTimeout(function(){
|
||||
message.fadeOut(function(){
|
||||
message.remove();
|
||||
});
|
||||
},duration || 2000);
|
||||
$(message).remove();
|
||||
message = $('<div />').html(msg).css({
|
||||
margin:0,
|
||||
padding:10,
|
||||
background: "#000",
|
||||
opacity:0.7,
|
||||
position:"fixed",
|
||||
top:10,
|
||||
right:10,
|
||||
fontFamily: 'Tahoma' ,
|
||||
color:'#fff',
|
||||
fontSize:12,
|
||||
borderRadius:12,
|
||||
width:'auto',
|
||||
height:'auto',
|
||||
textAlign:'center',
|
||||
textDecoration:'none'
|
||||
}).hide().fadeIn().appendTo('body');
|
||||
}
|
||||
|
||||
};
|
||||
})( jQuery );
|
||||
|
186
demo2.html
Normal file
@ -0,0 +1,186 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<script type="text/javascript" src="external/jquery-1.6.2.min.js"></script>
|
||||
<script type="text/javascript" src="build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('body').html2canvas();
|
||||
// var ss = $('ul').offset();
|
||||
// alert(ss.left);
|
||||
});
|
||||
</script>
|
||||
<title>
|
||||
display/box/float/clear test
|
||||
</title>
|
||||
<style type="text/css">
|
||||
/* last modified: 1 Dec 98 */
|
||||
|
||||
html {
|
||||
font: 10px/1 Verdana, sans-serif;
|
||||
background-color: blue;
|
||||
color: white;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 1.5em;
|
||||
border: .5em solid black;
|
||||
padding: 0;
|
||||
width: 48em;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin: 0;
|
||||
border: 0;
|
||||
padding: .5em;
|
||||
}
|
||||
|
||||
dt {
|
||||
background-color: rgb(204,0,0);
|
||||
margin: 0;
|
||||
padding: 1em;
|
||||
width: 10.638%; /* refers to parent element's width of 47em. = 5em or 50px */
|
||||
height: 28em;
|
||||
border: .5em solid black;
|
||||
float: left;
|
||||
}
|
||||
|
||||
dd {
|
||||
float: right;
|
||||
margin: 0 0 0 1em;
|
||||
border: 1em solid black;
|
||||
padding: 1em;
|
||||
width: 34em;
|
||||
height: 27em;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
display: block; /* i.e., suppress marker */
|
||||
color: black;
|
||||
height: 9em;
|
||||
width: 5em;
|
||||
margin: 0;
|
||||
border: .5em solid black;
|
||||
padding: 1em;
|
||||
float: left;
|
||||
background-color: #FC0;
|
||||
}
|
||||
|
||||
#bar {
|
||||
background-color: black;
|
||||
color: white;
|
||||
width: 41.17%; /* = 14em */
|
||||
border: 0;
|
||||
margin: 0 1em;
|
||||
}
|
||||
|
||||
#baz {
|
||||
margin: 1em 0;
|
||||
border: 0;
|
||||
padding: 1em;
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
form {
|
||||
margin: 0;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
form p {
|
||||
line-height: 1.9;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 1em 1em 1em 2em;
|
||||
border-width: 1em 1.5em 2em .5em;
|
||||
border-style: solid;
|
||||
border-color: black;
|
||||
padding: 1em 0;
|
||||
width: 5em;
|
||||
height: 9em;
|
||||
float: left;
|
||||
background-color: #FC0;
|
||||
color: black;
|
||||
}
|
||||
|
||||
address {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
h1 {
|
||||
background-color: black;
|
||||
color: white;
|
||||
float: left;
|
||||
margin: 1em 0;
|
||||
border: 0;
|
||||
padding: 1em;
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
font-weight: normal;
|
||||
font-size: 1em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<dl>
|
||||
<dt>
|
||||
toggle
|
||||
</dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li>
|
||||
the way
|
||||
</li>
|
||||
<li id="bar">
|
||||
<p>
|
||||
the world ends
|
||||
</p>
|
||||
<form action="./" method="get">
|
||||
<p>
|
||||
bang
|
||||
<input type="radio" name="foo" value="off">
|
||||
</p>
|
||||
<p>
|
||||
whimper
|
||||
<input type="radio" name="foo2" value="on">
|
||||
</p>
|
||||
</form>
|
||||
</li>
|
||||
<li>
|
||||
i grow old
|
||||
</li>
|
||||
<li id="baz">
|
||||
pluot?
|
||||
</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<address>
|
||||
bar maids,
|
||||
</address>
|
||||
</blockquote>
|
||||
<h1>
|
||||
sing to me, erbarme dich
|
||||
</h1>
|
||||
</dd>
|
||||
</dl>
|
||||
<p style="color: black; font-size: 1em; line-height: 1.3em; clear: both">
|
||||
This is a nonsensical document, but syntactically valid HTML 4.0. All 100% conformant CSS1 agents should be able to render the document elements above this paragraph <b>indistinguishably</b> (to the pixel) from this reference rendering, (except font rasterization and form widgets). All discrepancies should be traceable to CSS1 implementation shortcomings. Once you have finished evaluating this test, you can return to the <A HREF="sec5526c.htm" style="text-decoration:none">parent page</A>.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
72
demo3.html
Normal file
@ -0,0 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
|
||||
|
||||
<script type="text/javascript" src="external/jquery-1.6.2.min.js"></script>
|
||||
<script type="text/javascript" src="build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
|
||||
|
||||
$('body').html2canvas();
|
||||
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
.feedback-overlay-black{
|
||||
background-color:#000;
|
||||
opacity:0.5;
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
width:100%;
|
||||
height:100%;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<style>
|
||||
div{
|
||||
padding:20px;
|
||||
margin:0 auto;
|
||||
border:5px solid black;
|
||||
}
|
||||
|
||||
h1{
|
||||
border-bottom:2px solid white;
|
||||
}
|
||||
|
||||
h2{
|
||||
background: #efefef;
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="background:red;">
|
||||
<div style="background:green;">
|
||||
<div style="background:blue;border-color:white;">
|
||||
<div style="background:yellow;"><div style="background:orange;"><h1>Heading</h1>
|
||||
Text that isn't wrapped in anything.
|
||||
<p>Followed by some text wrapped in a <b><p> paragraph.</b> </p>
|
||||
Maybe add a <a href="#">link</a> or a different style of <a href="#" style="background:white;" id="highlight">link with a highlight</a>.
|
||||
<hr />
|
||||
<h2>More content</h2>
|
||||
<div style="width:10px;height:10px;border-width:10px;padding:0;">a</div>
|
||||
</div></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,183 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
display/box/float/clear test
|
||||
</title>
|
||||
<style type="text/css">
|
||||
/* last modified: 1 Dec 98 */
|
||||
|
||||
html {
|
||||
font: 10px/1 Verdana, sans-serif;
|
||||
background-color: blue;
|
||||
color: white;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 1.5em;
|
||||
border: .5em solid black;
|
||||
padding: 0;
|
||||
width: 48em;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin: 0;
|
||||
border: 0;
|
||||
padding: .5em;
|
||||
}
|
||||
|
||||
dt {
|
||||
background-color: rgb(204,0,0);
|
||||
margin: 0;
|
||||
padding: 1em;
|
||||
width: 10.638%; /* refers to parent element's width of 47em. = 5em or 50px */
|
||||
height: 28em;
|
||||
border: .5em solid black;
|
||||
float: left;
|
||||
}
|
||||
|
||||
dd {
|
||||
float: right;
|
||||
margin: 0 0 0 1em;
|
||||
border: 1em solid black;
|
||||
padding: 1em;
|
||||
width: 34em;
|
||||
height: 27em;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
display: block; /* i.e., suppress marker */
|
||||
color: black;
|
||||
height: 9em;
|
||||
width: 5em;
|
||||
margin: 0;
|
||||
border: .5em solid black;
|
||||
padding: 1em;
|
||||
float: left;
|
||||
background-color: #FC0;
|
||||
}
|
||||
|
||||
#bar {
|
||||
background-color: black;
|
||||
color: white;
|
||||
width: 41.17%; /* = 14em */
|
||||
border: 0;
|
||||
margin: 0 1em;
|
||||
}
|
||||
|
||||
#baz {
|
||||
margin: 1em 0;
|
||||
border: 0;
|
||||
padding: 1em;
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
form {
|
||||
margin: 0;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
form p {
|
||||
line-height: 1.9;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 1em 1em 1em 2em;
|
||||
border-width: 1em 1.5em 2em .5em;
|
||||
border-style: solid;
|
||||
border-color: black;
|
||||
padding: 1em 0;
|
||||
width: 5em;
|
||||
height: 9em;
|
||||
float: left;
|
||||
background-color: #FC0;
|
||||
color: black;
|
||||
}
|
||||
|
||||
address {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
h1 {
|
||||
background-color: black;
|
||||
color: white;
|
||||
float: left;
|
||||
margin: 1em 0;
|
||||
border: 0;
|
||||
padding: 1em;
|
||||
width: 10em;
|
||||
height: 10em;
|
||||
font-weight: normal;
|
||||
font-size: 1em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<dl>
|
||||
<dt>
|
||||
toggle
|
||||
</dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li>
|
||||
the way
|
||||
</li>
|
||||
<li id="bar">
|
||||
<p>
|
||||
the world ends
|
||||
</p>
|
||||
<form action="./" method="get">
|
||||
<p>
|
||||
bang
|
||||
<input type="radio" name="foo" value="off">
|
||||
</p>
|
||||
<p>
|
||||
whimper
|
||||
<input type="radio" name="foo2" value="on">
|
||||
</p>
|
||||
</form>
|
||||
</li>
|
||||
<li>
|
||||
i grow old
|
||||
</li>
|
||||
<li id="baz">
|
||||
pluot?
|
||||
</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<address>
|
||||
bar maids,
|
||||
</address>
|
||||
</blockquote>
|
||||
<h1>
|
||||
sing to me, erbarme dich
|
||||
</h1>
|
||||
</dd>
|
||||
</dl>
|
||||
<p style="color: black; font-size: 1em; line-height: 1.3em; clear: both">
|
||||
This is a nonsensical document, but syntactically valid HTML 4.0. All 100% conformant CSS1 agents should be able to render the document elements above this paragraph <b>indistinguishably</b> (to the pixel) from this reference rendering, (except font rasterization and form widgets). All discrepancies should be traceable to CSS1 implementation shortcomings. Once you have finished evaluating this test, you can return to the <A HREF="sec5526c.htm" style="text-decoration:none">parent page</A>.
|
||||
</p>
|
||||
<script type="text/javascript" src="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
html2canvas(document.body, {
|
||||
onrendered: function(canvas) {
|
||||
document.body.appendChild(canvas);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,65 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<style>
|
||||
.feedback-overlay-black{
|
||||
background-color:#000;
|
||||
opacity:0.5;
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
width:100%;
|
||||
height:100%;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<style>
|
||||
div{
|
||||
padding:20px;
|
||||
margin:0 auto;
|
||||
border:5px solid black;
|
||||
}
|
||||
|
||||
h1{
|
||||
border-bottom:2px solid white;
|
||||
}
|
||||
|
||||
h2{
|
||||
background: #efefef;
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="background:red;">
|
||||
<div style="background:green;">
|
||||
<div style="background:blue;border-color:white;">
|
||||
<div style="background:yellow;"><div style="background:orange;"><h1>Heading</h1>
|
||||
Text that isn't wrapped in anything.
|
||||
<p>Followed by some text wrapped in a <b><p> paragraph.</b> </p>
|
||||
Maybe add a <a href="#">link</a> or a different style of <a href="#" style="background:white;" id="highlight">link with a highlight</a>.
|
||||
<hr />
|
||||
<h2>More content</h2>
|
||||
<div style="width:10px;height:10px;border-width:10px;padding:0;">a</div>
|
||||
</div></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript" src="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
html2canvas(document.body, {
|
||||
onrendered: function(canvas) {
|
||||
document.body.appendChild(canvas);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
18
external/jquery-1.6.2.min.js
vendored
Normal file
BIN
lib/compiler.jar
Normal file
1204
lib/jquery-1.4.4.externs.js
Normal file
BIN
loading.gif
Normal file
After Width: | Height: | Size: 8.0 KiB |
46
package.json
@ -1,46 +0,0 @@
|
||||
{
|
||||
"title": "html2canvas",
|
||||
"name": "html2canvas",
|
||||
"description": "Screenshots with JavaScript",
|
||||
"version": "0.4.1",
|
||||
"author": {
|
||||
"name": "Niklas von Hertzen",
|
||||
"email": "niklasvh@gmail.com",
|
||||
"url": "http://hertzen.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
"dependencies": {},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:niklasvh/html2canvas.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/niklasvh/html2canvas/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"grunt": ">=0.4.0",
|
||||
"grunt-contrib-concat": "*",
|
||||
"grunt-contrib-uglify": "*",
|
||||
"grunt-contrib-jshint": "*",
|
||||
"grunt-contrib-qunit": "*",
|
||||
"grunt-contrib-watch": "~0.5.1",
|
||||
"googleapis": "~0.4.3",
|
||||
"jwt-sign": "~0.1.0",
|
||||
"base64-arraybuffer": ">= 0.1.0",
|
||||
"png-js": ">= 0.1.1",
|
||||
"sync-webdriver": ">=0.1.1",
|
||||
"express": "~3.2.3",
|
||||
"baconjs": "~0.3.15"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "grunt travis --verbose"
|
||||
},
|
||||
"homepage": "http://html2canvas.hertzen.com",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT"
|
||||
}
|
||||
]
|
||||
}
|
120
readme.md
@ -1,122 +1,36 @@
|
||||
html2canvas
|
||||
===========
|
||||
|
||||
### Current build status ###
|
||||
[](https://travis-ci.org/niklasvh/html2canvas)
|
||||
|
||||
#### JavaScript HTML renderer ####
|
||||
|
||||
The script allows you to take "screenshots" of webpages or parts of it, directly on the users browser. The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.
|
||||
|
||||
This script allows you to take "screenshots" of webpages or parts of it, directly on the users browser. The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.
|
||||
|
||||
|
||||
###How does it work?###
|
||||
The script renders the current page as a canvas image, by reading the DOM and the different styles applied to the elements.
|
||||
The script renders the current page as a canvas image, by reading the DOM and the different styles applied to the elements. However, as many elements are displayed differently on different browsers and operating systems (such as form elements such as radio buttons or checkboxes) as well as
|
||||
|
||||
It does **not require any rendering from the server**, as the whole image is created on the **clients browser**. However, as it is heavily dependent on the browser, this library is *not suitable* to be used in nodejs.
|
||||
It doesn't magically circumvent any browser content policy restrictions either, so rendering cross-origin content will require a [proxy](https://github.com/niklasvh/html2canvas/wiki/Proxies) to get the content to the [same origin](http://en.wikipedia.org/wiki/Same_origin_policy).
|
||||
It does <b>not require any rendering from the server</b>, as the whole image is created on the <b>clients browser</b>. However, for browsers without <code>canvas</code> support alternatives such as <a href="http://flashcanvas.net/">flashcanvas</a> or <a href="http://excanvas.sourceforge.net/">ExplorerCanvas</a> are necessary to create the image.
|
||||
|
||||
The script is still in a **very experimental state**, so I don't recommend using it in a production environment nor start building applications with it yet, as there will be still major changes made.
|
||||
Additionally, to render <code>iframe</code> content or images situated outside of the <a href="http://en.wikipedia.org/wiki/Same_origin_policy">same origin policy</a> a proxy will be necessary to load the content to the users browser.
|
||||
|
||||
The script is still in a very experimental state, so I don't recommend using it in a production environment nor start building applications with it yet, as there will be still major changes made. However, please do test it out and report your findings, especially if something should be working, but is displaying it incorrectly.
|
||||
|
||||
###Browser compatibility###
|
||||
|
||||
The script should work fine on the following browsers:
|
||||
|
||||
* Firefox 3.5+
|
||||
* Google Chrome
|
||||
* Opera 12+
|
||||
* IE9+
|
||||
* Safari 6+
|
||||
* Google Chrome
|
||||
* Newer versions of Opera (exactly how new is yet to be determined)
|
||||
* >=IE9 (Older versions compatible with the use of flashcanvas)
|
||||
|
||||
Note that the compatibility will most likely be increased in future builds, as many of the current restrictions have at least partial work arounds, which can be used with older browser versions.
|
||||
|
||||
As each CSS property needs to be manually built to be supported, there are a number of properties that are not yet supported.
|
||||
|
||||
### Usage ###
|
||||
To render an `element` with html2canvas, simply call:
|
||||
` html2canvas(element, options);`
|
||||
|
||||
To access the created canvas, provide the `onrendered` event in the options which returns the canvas element as the first argument, as such:
|
||||
|
||||
html2canvas(document.body, {
|
||||
onrendered: function(canvas) {
|
||||
/* canvas is the actual canvas element,
|
||||
to append it to the page call for example
|
||||
document.body.appendChild( canvas );
|
||||
*/
|
||||
}
|
||||
});
|
||||
|
||||
### Building ###
|
||||
|
||||
The library uses [grunt](http://gruntjs.com/) for building. Alternatively, you can download the latest build from [here](http://html2canvas.hertzen.com/build/html2canvas.js).
|
||||
|
||||
Run the full build process (including lint, qunit and webdriver tests):
|
||||
|
||||
$ grunt
|
||||
|
||||
Skip lint and tests and simply build from source:
|
||||
|
||||
$ grunt build
|
||||
|
||||
### Running tests ###
|
||||
|
||||
The library has two sets of tests. The first set is a number of qunit tests that check that different values parsed by browsers are correctly converted in html2canvas. To run these tests with grunt you'll need [phantomjs](http://phantomjs.org/).
|
||||
|
||||
The other set of tests run Firefox, Chrome and Internet Explorer with [webdriver](https://github.com/niklasvh/webdriver.js). The selenium standalone server (runs on Java) is required for these tests and can be downloaded from [here](http://code.google.com/p/selenium/downloads/list). They capture an actual screenshot from the test pages and compare the image to the screenshot created by html2canvas and calculate the percentage differences. These tests generally aren't expected to provide 100% matches, but while commiting changes, these should generally not go decrease from the baseline values.
|
||||
|
||||
Start by downloading the dependencies:
|
||||
|
||||
$ npm install
|
||||
|
||||
Run qunit tests:
|
||||
|
||||
$ grunt test
|
||||
###So what isn't included yet?###
|
||||
|
||||
There are still a lot of CSS properties missing, including most CSS3 properties such as <code>text-shadow</code>, <code>box-radius</code> etc. as well as all elements created by the browser, such as radio and checkbox buttons and list icons. I will compile a full list of supported elements and CSS properties soon.
|
||||
There is no support for <code>frame</code> and <code>object</code> content such as Flash.
|
||||
|
||||
### Examples ###
|
||||
|
||||
For more information and examples, please visit the [homepage](http://html2canvas.hertzen.com) or try the [test console](http://html2canvas.hertzen.com/screenshots.html).
|
||||
|
||||
### Contributing ###
|
||||
|
||||
If you wish to contribute to the project, please send the pull requests to the develop branch. Before submitting any changes, try and test that the changes work with all the support browsers. If some CSS property isn't supported or is incomplete, please create appropriate tests for it as well before submitting any code changes.
|
||||
|
||||
### Changelog ###
|
||||
|
||||
v0.4.1 - 7.9.2013
|
||||
* Added support for bower
|
||||
* Improved z-index ordering
|
||||
* Basic implementation for CSS transformations
|
||||
* Fixed inline text in top element
|
||||
* Basic implementation for text-shadow
|
||||
|
||||
v0.4.0 - 30.1.2013
|
||||
* Added rendering tests with <a href="https://github.com/niklasvh/webdriver.js">webdriver</a>
|
||||
* Switched to using grunt for building
|
||||
* Removed support for IE<9, including any FlashCanvas bits
|
||||
* Support for border-radius
|
||||
* Support for multiple background images, size, and clipping
|
||||
* Support for :before and :after pseudo elements
|
||||
* Support for placeholder rendering
|
||||
* Reformatted all tests to small units to test specific features
|
||||
|
||||
v0.3.4 - 26.6.2012
|
||||
|
||||
* Removed (last?) jQuery dependencies (<a href="https://github.com/niklasvh/html2canvas/commit/343b86705fe163766fcf735eb0217130e4bd5b17">niklasvh</a>)
|
||||
* SVG-powered rendering (<a href="https://github.com/niklasvh/html2canvas/commit/67d3e0d0f59a5a654caf71a2e3be6494ff146c75">niklasvh</a>)
|
||||
* Radial gradients (<a href="https://github.com/niklasvh/html2canvas/commit/4f22c18043a73c0c3bbf3b5e4d62714c56acd3c7">SunboX</a>)
|
||||
* Split renderers to their own objects (<a href="https://github.com/niklasvh/html2canvas/commit/94f2f799a457cd29a21cc56ef8c06f1697866739">niklasvh</a>)
|
||||
* Simplified API, cleaned up code (<a href="https://github.com/niklasvh/html2canvas/commit/c7d526c9eaa6a4abf4754d205fe1dee360c7660e">niklasvh</a>)
|
||||
|
||||
v0.3.3 - 2.3.2012
|
||||
|
||||
* SVG taint fix, and additional taint testing options for rendering (<a href="https://github.com/niklasvh/html2canvas/commit/2dc8b9385e656696cb019d615bdfa1d98b17d5d4">niklasvh</a>)
|
||||
* Added support for CORS images and option to create canvas as tainted (<a href="https://github.com/niklasvh/html2canvas/commit/3ad49efa0032cde25c6ed32a39e35d1505d3b2ef">niklasvh</a>)
|
||||
* Improved minification saved ~1K! (<a href="https://github.com/cobexer/html2canvas/commit/b82be022b2b9240bd503e078ac980bde2b953e43">cobexer</a>)
|
||||
* Added integrated support for Flashcanvas (<a href="https://github.com/niklasvh/html2canvas/commit/e9257191519f67d74fd5e364d8dee3c0963ba5fc">niklasvh</a>)
|
||||
* Fixed a variety of legacy IE bugs (<a href="https://github.com/niklasvh/html2canvas/commit/b65357c55d0701017bafcd357bc654b54d458f8f">niklasvh</a>)
|
||||
|
||||
v0.3.2 - 20.2.2012
|
||||
|
||||
* Added changelog!
|
||||
* Added bookmarklet (<a href="https://github.com/niklasvh/html2canvas/commit/b320dd306e1a2d32a3bc5a71b6ebf6d8c060cde5">cobexer</a>)
|
||||
* Option to select single element to render (<a href="https://github.com/niklasvh/html2canvas/commit/0cb252ada91c84ef411288b317c03e97da1f12ad">niklasvh</a>)
|
||||
* Fixed closure compiler warnings (<a href="https://github.com/niklasvh/html2canvas/commit/36ff1ec7aadcbdf66851a0b77f0b9e87e4a8e4a1">cobexer</a>)
|
||||
* Enable profiling in FF (<a href="https://github.com/niklasvh/html2canvas/commit/bbd75286a8406cf9e5aea01fdb7950d547edefb9">cobexer</a>)
|
||||
For more information and examples, please visit the <a href="http://html2canvas.hertzen.com">homepage</a> or try the <a href="http://html2canvas.hertzen.com/screenshots.html">test console</a>.
|
326
screenshots.html
Normal file
@ -0,0 +1,326 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>JavaScript screenshot creator</title>
|
||||
|
||||
<style type="text/css">
|
||||
a {
|
||||
color: #0B0B0B;
|
||||
background-color: #FDF9EE;
|
||||
padding: 0 8px;
|
||||
text-decoration: none;
|
||||
font: normal 12px/16px "Trebuchet MS", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #0B0B0B;
|
||||
background-color: #EFEBDE;
|
||||
padding: 0 8px;
|
||||
text-decoration: none;
|
||||
font: normal 12px/16px "Trebuchet MS", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
body {
|
||||
font: normal 14px/19px Arial, Helvetica, sans-serif;
|
||||
background-color: white;
|
||||
color: #4E4628;
|
||||
}
|
||||
|
||||
textarea {
|
||||
background-color: #EFEBDE;
|
||||
color: #0B0B0B;
|
||||
border: #C3BCA4 1px solid;
|
||||
|
||||
|
||||
|
||||
|
||||
font: normal 11px Arial, Helvetica, sans-serif;
|
||||
width:300px;
|
||||
height:150px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
background-color: white;
|
||||
color: #0B0B0B;
|
||||
font: normal 28px/46px Georgia, "Times New Roman", Times, serif;
|
||||
margin:0;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
h3 {
|
||||
|
||||
color: #786E4E;
|
||||
padding: 0 0 10px 55px;
|
||||
|
||||
|
||||
height: 37px;
|
||||
font: normal 24px/30px Georgia, "Times New Roman", Times, serif;
|
||||
}
|
||||
ul{
|
||||
float:left;
|
||||
margin:0;
|
||||
|
||||
}
|
||||
|
||||
table{
|
||||
margin:0 auto;
|
||||
width:400px;
|
||||
border:1px solid black;
|
||||
}
|
||||
#content{
|
||||
clear:both;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
#about{
|
||||
padding:0 10px;
|
||||
width:450px;
|
||||
float:left;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" src="external/jquery-1.6.2.min.js"></script>
|
||||
<script type="text/javascript" src="build/html2canvas.js?221"></script>
|
||||
<script type="text/javascript" src="build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript" src="http://www.hertzen.com/js/ganalytics-heatmap.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
var date = new Date();
|
||||
var message,
|
||||
timeoutTimer,
|
||||
timer;
|
||||
|
||||
var proxyUrl = "http://html2canvas.appspot.com";
|
||||
|
||||
function addRow(table,field,val){
|
||||
var tr = $('<tr />').appendTo( $(table));
|
||||
|
||||
tr.append($('<td />').css('font-weight','bold').text(field)).append($('<td />').text(val));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
function throwMessage(msg,duration){
|
||||
|
||||
window.clearTimeout(timeoutTimer);
|
||||
timeoutTimer = window.setTimeout(function(){
|
||||
message.fadeOut(function(){
|
||||
message.remove();
|
||||
});
|
||||
},duration || 2000);
|
||||
$(message).remove();
|
||||
message = $('<div />').html(msg).css({
|
||||
margin:0,
|
||||
padding:10,
|
||||
background: "#000",
|
||||
opacity:0.7,
|
||||
position:"fixed",
|
||||
top:10,
|
||||
right:10,
|
||||
fontFamily: 'Tahoma' ,
|
||||
color:'#fff',
|
||||
fontSize:12,
|
||||
borderRadius:12,
|
||||
width:'auto',
|
||||
height:'auto',
|
||||
textAlign:'center',
|
||||
textDecoration:'none'
|
||||
}).hide().fadeIn().appendTo('body');
|
||||
}
|
||||
|
||||
$(function(){
|
||||
|
||||
$('ul li a').click(function(e){
|
||||
e.preventDefault();
|
||||
$('#url').val(this.href);
|
||||
$('button').click();
|
||||
})
|
||||
|
||||
var iframe,d;
|
||||
|
||||
|
||||
|
||||
|
||||
$('input[type="button"]').click(function(){
|
||||
$(iframe.contentWindow).unbind('load');
|
||||
$(iframe).contents().find('body').html2canvas({
|
||||
canvasHeight: d.body.scrollHeight,
|
||||
canvasWidth: d.body.scrollWidth,
|
||||
logging:true
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$('button').click(function(){
|
||||
|
||||
$(this).prop('disabled',true);
|
||||
var url = $('#url').val();
|
||||
$('#content').append($('<img />').attr('src','loading.gif').css('margin-top',40));
|
||||
|
||||
var urlParts = document.createElement('a');
|
||||
urlParts.href = url;
|
||||
|
||||
$.ajax({
|
||||
data: {
|
||||
xhr2:false,
|
||||
url:urlParts.href
|
||||
|
||||
},
|
||||
url: proxyUrl,
|
||||
dataType: "jsonp",
|
||||
success: function(html){
|
||||
|
||||
|
||||
iframe = document.createElement('iframe');
|
||||
$(iframe).css({
|
||||
'visibility':'hidden'
|
||||
}).width($(window).width()).height($(window).height());
|
||||
$('#content').append(iframe);
|
||||
d = iframe.contentWindow.document;
|
||||
|
||||
d.open();
|
||||
|
||||
$(iframe.contentWindow).load(function(){
|
||||
|
||||
timer = date.getTime();
|
||||
|
||||
$(iframe).contents().find('body').html2canvas({
|
||||
canvasHeight: d.body.scrollHeight,
|
||||
canvasWidth: d.body.scrollWidth,
|
||||
logging:true,
|
||||
proxyUrl: proxyUrl,
|
||||
logger:function(msg){
|
||||
$('#logger').val(function(e,i){
|
||||
return i+"\n"+msg;
|
||||
});
|
||||
|
||||
},
|
||||
ready: function(renderer) {
|
||||
$('button').prop('disabled',false);
|
||||
$("#content").empty();
|
||||
var finishTime = new Date();
|
||||
|
||||
var table = $('<table />');
|
||||
$('#content')
|
||||
.append('<h2>Screenshot</h2>')
|
||||
.append(renderer.canvas)
|
||||
.append('<h3>Details</h3>')
|
||||
.append(table);
|
||||
|
||||
|
||||
|
||||
addRow(table,"Creation time",((finishTime.getTime()-timer)/1000) + " seconds");
|
||||
addRow(table,"Total draws", renderer.numDraws);
|
||||
addRow(table,"Context stacks", renderer.contextStacks.length);
|
||||
addRow(table,"Loaded images", renderer.images.length/2);
|
||||
addRow(table,"Performed z-index reorder", renderer.needReorder);
|
||||
addRow(table,"Used rangeBounds", renderer.support.rangeBounds);
|
||||
|
||||
|
||||
|
||||
throwMessage('Screenshot created in '+ ((finishTime.getTime()-timer)/1000) + " seconds<br />Total of "+renderer.numDraws+" draws performed",4000);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$('base').attr('href',urlParts.protocol+"//"+urlParts.hostname+"/");
|
||||
html = html.replace("<head>","<head><base href='"+urlParts.protocol+"//"+urlParts.hostname+"/' />");
|
||||
if ($("#disablejs").prop('checked')){
|
||||
html = html.replace(/\<script/gi,"<!--<script");
|
||||
html = html.replace(/\<\/script\>/gi,"<\/script>-->");
|
||||
}
|
||||
// console.log(html);
|
||||
d.write(html);
|
||||
|
||||
d.close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
var _gaq = _gaq || [];_gaq.push(['_setAccount', 'UA-188600-10']);_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();
|
||||
|
||||
</script>
|
||||
<base />
|
||||
</head>
|
||||
<body>
|
||||
<!-- <div style="background:red;padding:10px;color:#fff">
|
||||
App engine proxy is <a href="http://twitter.com/#!/Niklasvh/status/96265826713350144">temporarily out of use</a> due to exceeded bandwidth use. Please try again tomorrow or meanwhile check other examples <a href="http://html2canvas.hertzen.com/">here</a>.
|
||||
</div>-->
|
||||
|
||||
<div style="float:left;width:500px;">
|
||||
<h1>JavaScript screenshot creator</h1>
|
||||
<label for="url">Website URL:</label>
|
||||
<input type="url" id="url" value="http://www.yahoo.com" /><button>Get screenshot!</button>
|
||||
<!-- <input type="button" value="Try anyway" />--><br />
|
||||
|
||||
|
||||
<label for="disablejs">Disable JavaScript (recommended, doesn't work well with the proxy)</label> <input type="checkbox" id="disablejs" checked /><br />
|
||||
<small>Tested with Google Chrome 12, Firefox 4 and Opera 11.5</small>
|
||||
</div>
|
||||
<div style="float:right;">
|
||||
<div style="margin-left:17px;float:right;">
|
||||
<!-- Place this tag in your head or just before your close body tag -->
|
||||
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
|
||||
|
||||
<!-- Place this tag where you want the +1 button to render -->
|
||||
<g:plusone size="tall"></g:plusone>
|
||||
</div>
|
||||
|
||||
<div style="float:right;">
|
||||
|
||||
<a href="http://twitter.com/share" class="twitter-share-button" data-url="http://html2canvas.hertzen.com/" data-text="html2canvas - screenshots with #JavaScript" data-count="vertical" data-via="niklasvh">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
<h3>Recommended (tested) pages:</h3>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><a href="http://www.yahoo.com">yahoo.com</a></li>
|
||||
<li><a href="http://www.google.com">google.com</a></li>
|
||||
<li><a href="https://github.com/niklasvh/html2canvas">github.com</a></li>
|
||||
<li><a href="http://www.smashingmagazine.com">smashingmagazine.com</a></li>
|
||||
<li><a href="http://www.mashable.com">mashable.com</a></li>
|
||||
<li><a href="http://www.facebook.com/google">facebook.com/google</a></li>
|
||||
<li><a href="http://www.youtube.com/">youtube.com</a></li>
|
||||
<li><a href="http://www.cnn.com/">cnn.com</a></li>
|
||||
|
||||
<li><a href="http://www.engadget.com/">engadget.com (lot of elements, very slow)</a></li>
|
||||
<li><a href="http://eu.battle.net/en/">battle.net</a></li>
|
||||
|
||||
|
||||
</ul>
|
||||
<div style="float:left;">
|
||||
<textarea id="logger"></textarea>
|
||||
</div>
|
||||
<div id="about"><b> About</b><br />
|
||||
The whole screenshot is created with JavaScript. The only server interaction that is happening on this page is the proxy for loading the external pages/images into JSONP/CORS enabled page and onwards onto the JavaScript renderer script.
|
||||
There are a lot of problems of loading external pages, even with a proxy, and as such many pages will not render at all. If you wish to try the script properly, I recommend you get a copy of the source from <a href="https://github.com/niklasvh/html2canvas">here</a> instead.
|
||||
</div>
|
||||
<div id="content"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
300
src/Background.js
Normal file
@ -0,0 +1,300 @@
|
||||
|
||||
|
||||
html2canvas.prototype.drawBackground = function(el,bounds,ctx){
|
||||
|
||||
// TODO add support for multi background-images
|
||||
var background_image = this.getCSS(el,"background-image").split(",")[0];
|
||||
var background_repeat = this.getCSS(el,"background-repeat").split(",")[0];
|
||||
|
||||
if (typeof background_image != "undefined" && /^(1|none)$/.test(background_image)==false && /^(-webkit|-moz|linear-gradient|-o-)/.test(background_image)==false){
|
||||
|
||||
background_image = this.backgroundImageUrl(background_image);
|
||||
var image = this.loadImage(background_image);
|
||||
|
||||
|
||||
var bgp = this.getBackgroundPosition(el,bounds,image),
|
||||
bgy;
|
||||
|
||||
if (image){
|
||||
switch(background_repeat){
|
||||
|
||||
case "repeat-x":
|
||||
this.drawbackgroundRepeatX(ctx,image,bgp,bounds.left,bounds.top,bounds.width,bounds.height);
|
||||
break;
|
||||
|
||||
case "repeat-y":
|
||||
this.drawbackgroundRepeatY(ctx,image,bgp,bounds.left,bounds.top,bounds.width,bounds.height);
|
||||
break;
|
||||
|
||||
case "no-repeat":
|
||||
/*
|
||||
this.drawBackgroundRepeat(
|
||||
ctx,
|
||||
image,
|
||||
bgp.left+bounds.left, // sx
|
||||
bgp.top+bounds.top, // sy
|
||||
Math.min(bounds.width,image.width),
|
||||
Math.min(bounds.height,image.height),
|
||||
bounds.left,
|
||||
bounds.top
|
||||
);*/
|
||||
|
||||
|
||||
// console.log($(el).css('background-image'));
|
||||
var bgw = bounds.width-bgp.left,
|
||||
bgh = bounds.height-bgp.top,
|
||||
bgsx = bgp.left,
|
||||
bgsy = bgp.top,
|
||||
bgdx = bgp.left+bounds.left,
|
||||
bgdy = bgp.top+bounds.top;
|
||||
|
||||
//
|
||||
// bgw = Math.min(bgw,image.width);
|
||||
// bgh = Math.min(bgh,image.height);
|
||||
|
||||
if (bgsx<0){
|
||||
bgsx = Math.abs(bgsx);
|
||||
bgdx += bgsx;
|
||||
bgw = Math.min(bounds.width,image.width-bgsx);
|
||||
}else{
|
||||
bgw = Math.min(bgw,image.width);
|
||||
bgsx = 0;
|
||||
}
|
||||
|
||||
if (bgsy<0){
|
||||
bgsy = Math.abs(bgsy);
|
||||
bgdy += bgsy;
|
||||
// bgh = bgh-bgsy;
|
||||
bgh = Math.min(bounds.height,image.height-bgsy);
|
||||
}else{
|
||||
bgh = Math.min(bgh,image.height);
|
||||
bgsy = 0;
|
||||
}
|
||||
|
||||
|
||||
// bgh = Math.abs(bgh);
|
||||
// bgw = Math.abs(bgw);
|
||||
if (bgh>0 && bgw > 0){
|
||||
this.drawImage(
|
||||
ctx,
|
||||
image,
|
||||
bgsx, // source X : 0
|
||||
bgsy, // source Y : 1695
|
||||
bgw, // source Width : 18
|
||||
bgh, // source Height : 1677
|
||||
bgdx, // destination X :906
|
||||
bgdy, // destination Y : 1020
|
||||
bgw, // destination width : 18
|
||||
bgh // destination height : 1677
|
||||
);
|
||||
|
||||
// ctx.drawImage(image,(bounds.left+bgp.left),(bounds.top+bgp.top));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
var height,
|
||||
add;
|
||||
|
||||
|
||||
bgp.top = bgp.top-Math.ceil(bgp.top/image.height)*image.height;
|
||||
|
||||
|
||||
for(bgy=(bounds.top+bgp.top);bgy<bounds.height+bounds.top;){
|
||||
|
||||
|
||||
|
||||
var h = Math.min(image.height,(bounds.height+bounds.top)-bgy);
|
||||
|
||||
|
||||
if ( Math.floor(bgy+image.height)>h+bgy){
|
||||
height = (h+bgy)-bgy;
|
||||
}else{
|
||||
height = image.height;
|
||||
}
|
||||
// console.log(height);
|
||||
|
||||
if (bgy<bounds.top){
|
||||
add = bounds.top-bgy;
|
||||
bgy = bounds.top;
|
||||
|
||||
}else{
|
||||
add = 0;
|
||||
}
|
||||
|
||||
this.drawbackgroundRepeatX(ctx,image,bgp,bounds.left,bgy,bounds.width,height);
|
||||
if (add>0){
|
||||
bgp.top += add;
|
||||
}
|
||||
bgy = Math.floor(bgy+image.height)-add;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
}else{
|
||||
|
||||
this.log("Error loading background:" + background_image);
|
||||
//console.log(images);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Function to retrieve the actual src of a background-image
|
||||
*/
|
||||
|
||||
html2canvas.prototype.backgroundImageUrl = function(src){
|
||||
if (src.substr(0,5)=='url("'){
|
||||
src = src.substr(5);
|
||||
src = src.substr(0,src.length-2);
|
||||
}else{
|
||||
src = src.substr(4);
|
||||
src = src.substr(0,src.length-1);
|
||||
}
|
||||
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function to retrieve background-position, both in pixels and %
|
||||
*/
|
||||
|
||||
html2canvas.prototype.getBackgroundPosition = function(el,bounds,image){
|
||||
// TODO add support for multi image backgrounds
|
||||
|
||||
var bgpos = this.getCSS(el,"backgroundPosition").split(",")[0] || "0 0";
|
||||
// var bgpos = $(el).css("backgroundPosition") || "0 0";
|
||||
var bgposition = bgpos.split(" "),
|
||||
topPos,
|
||||
left,
|
||||
percentage;
|
||||
|
||||
if (bgposition.length==1){
|
||||
var val = bgposition,
|
||||
bgposition = [];
|
||||
|
||||
bgposition[0] = val,
|
||||
bgposition[1] = val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (bgposition[0].toString().indexOf("%")!=-1){
|
||||
|
||||
percentage = (parseFloat(bgposition[0])/100);
|
||||
left = ((bounds.width * percentage)-(image.width*percentage));
|
||||
|
||||
}else{
|
||||
left = parseInt(bgposition[0],10);
|
||||
}
|
||||
|
||||
if (bgposition[1].toString().indexOf("%")!=-1){
|
||||
|
||||
percentage = (parseFloat(bgposition[1])/100);
|
||||
topPos = ((bounds.height * percentage)-(image.height*percentage));
|
||||
}else{
|
||||
|
||||
topPos = parseInt(bgposition[1],10);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
var returnObj = {}
|
||||
/*
|
||||
"top": topPos,
|
||||
"left": left
|
||||
};*/
|
||||
|
||||
|
||||
returnObj.top = topPos;
|
||||
returnObj.left = left;
|
||||
|
||||
|
||||
|
||||
return returnObj;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
html2canvas.prototype.drawbackgroundRepeatY = function(ctx,image,bgp,x,y,w,h){
|
||||
|
||||
var height,
|
||||
width = Math.min(image.width,w),bgy;
|
||||
|
||||
bgp.top = bgp.top-Math.ceil(bgp.top/image.height)*image.height;
|
||||
|
||||
|
||||
for(bgy=(y+bgp.top);bgy<h+y;){
|
||||
|
||||
|
||||
if ( Math.floor(bgy+image.height)>h+y){
|
||||
height = (h+y)-bgy;
|
||||
}else{
|
||||
height = image.height;
|
||||
}
|
||||
this.drawBackgroundRepeat(ctx,image,x+bgp.left,bgy,width,height,x,y);
|
||||
|
||||
bgy = Math.floor(bgy+image.height);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
html2canvas.prototype.drawbackgroundRepeatX = function(ctx,image,bgp,x,y,w,h){
|
||||
|
||||
var height = Math.min(image.height,h),
|
||||
width,bgx;
|
||||
|
||||
|
||||
bgp.left = bgp.left-Math.ceil(bgp.left/image.width)*image.width;
|
||||
|
||||
|
||||
for(bgx=(x+bgp.left);bgx<w+x;){
|
||||
|
||||
if (Math.floor(bgx+image.width)>w+x){
|
||||
width = (w+x)-bgx;
|
||||
}else{
|
||||
width = image.width;
|
||||
}
|
||||
|
||||
this.drawBackgroundRepeat(ctx,image,bgx,(y+bgp.top),width,height,x,y);
|
||||
|
||||
bgx = Math.floor(bgx+image.width);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
html2canvas.prototype.drawBackgroundRepeat = function(ctx,image,x,y,width,height,elx,ely){
|
||||
var sourceX = 0,
|
||||
sourceY=0;
|
||||
if (elx-x>0){
|
||||
sourceX = elx-x;
|
||||
}
|
||||
|
||||
if (ely-y>0){
|
||||
sourceY = ely-y;
|
||||
}
|
||||
|
||||
this.drawImage(
|
||||
ctx,
|
||||
image,
|
||||
sourceX, // source X
|
||||
sourceY, // source Y
|
||||
width-sourceX, // source Width
|
||||
height-sourceY, // source Height
|
||||
x+sourceX, // destination X
|
||||
y+sourceY, // destination Y
|
||||
width-sourceX, // destination width
|
||||
height-sourceY // destination height
|
||||
);
|
||||
}
|
85
src/Border.js
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Function to provide border details for an element
|
||||
*/
|
||||
|
||||
html2canvas.prototype.getBorderData = function(el){
|
||||
|
||||
var borders = [];
|
||||
var _ = this;
|
||||
this.each(["top","right","bottom","left"],function(i,borderSide){
|
||||
borders.push({
|
||||
width: parseInt(_.getCSS(el,'border-'+borderSide+'-width'),10),
|
||||
color: _.getCSS(el,'border-'+borderSide+'-color')
|
||||
});
|
||||
});
|
||||
|
||||
return borders;
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.drawBorders = function(el,ctx, bounds,clip){
|
||||
|
||||
|
||||
var x = bounds.left;
|
||||
var y = bounds.top;
|
||||
var w = bounds.width;
|
||||
var h = bounds.height;
|
||||
|
||||
/*
|
||||
* TODO add support for different border-style's than solid
|
||||
*/
|
||||
var borders = this.getBorderData(el);
|
||||
var _ = this;
|
||||
|
||||
this.each(borders,function(borderSide,borderData){
|
||||
if (borderData.width>0){
|
||||
var bx = x,
|
||||
by = y,
|
||||
bw = w,
|
||||
bh = h-(borders[2].width);
|
||||
switch(borderSide){
|
||||
case 0:
|
||||
// top border
|
||||
bh = borders[0].width;
|
||||
break;
|
||||
case 1:
|
||||
// right border
|
||||
bx = x+w-(borders[1].width);
|
||||
bw = borders[1].width;
|
||||
break;
|
||||
case 2:
|
||||
// bottom border
|
||||
by = (by+h)-(borders[2].width);
|
||||
bh = borders[2].width;
|
||||
break;
|
||||
case 3:
|
||||
// left border
|
||||
bw = borders[3].width;
|
||||
break;
|
||||
}
|
||||
|
||||
var borderBounds = {
|
||||
left:bx,
|
||||
top:by,
|
||||
width: bw,
|
||||
height:bh
|
||||
};
|
||||
|
||||
if (clip){
|
||||
borderBounds = _.clipBounds(borderBounds,clip);
|
||||
}
|
||||
|
||||
|
||||
if (borderBounds.width>0 && borderBounds.height>0){
|
||||
_.newRect(ctx,bx,by,borderBounds.width,borderBounds.height,borderData.color);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return borders;
|
||||
|
||||
};
|
628
src/Core.js
@ -1,410 +1,260 @@
|
||||
"use strict";
|
||||
/**
|
||||
* Creates a render of the element el
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
var _html2canvas = {},
|
||||
previousElement,
|
||||
computedCSS,
|
||||
html2canvas;
|
||||
function html2canvas(el, userOptions) {
|
||||
|
||||
_html2canvas.Util = {};
|
||||
|
||||
_html2canvas.Util.log = function(a) {
|
||||
if (_html2canvas.logging && window.console && window.console.log) {
|
||||
window.console.log(a);
|
||||
}
|
||||
};
|
||||
|
||||
_html2canvas.Util.trimText = (function(isNative){
|
||||
return function(input) {
|
||||
return isNative ? isNative.apply(input) : ((input || '') + '').replace( /^\s+|\s+$/g , '' );
|
||||
};
|
||||
})(String.prototype.trim);
|
||||
|
||||
_html2canvas.Util.asFloat = function(v) {
|
||||
return parseFloat(v);
|
||||
};
|
||||
|
||||
(function() {
|
||||
// TODO: support all possible length values
|
||||
var TEXT_SHADOW_PROPERTY = /((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g;
|
||||
var TEXT_SHADOW_VALUES = /(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g;
|
||||
_html2canvas.Util.parseTextShadows = function (value) {
|
||||
if (!value || value === 'none') {
|
||||
return [];
|
||||
}
|
||||
|
||||
// find multiple shadow declarations
|
||||
var shadows = value.match(TEXT_SHADOW_PROPERTY),
|
||||
results = [];
|
||||
for (var i = 0; shadows && (i < shadows.length); i++) {
|
||||
var s = shadows[i].match(TEXT_SHADOW_VALUES);
|
||||
results.push({
|
||||
color: s[0],
|
||||
offsetX: s[1] ? s[1].replace('px', '') : 0,
|
||||
offsetY: s[2] ? s[2].replace('px', '') : 0,
|
||||
blur: s[3] ? s[3].replace('px', '') : 0
|
||||
});
|
||||
}
|
||||
return results;
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
_html2canvas.Util.parseBackgroundImage = function (value) {
|
||||
var whitespace = ' \r\n\t',
|
||||
method, definition, prefix, prefix_i, block, results = [],
|
||||
c, mode = 0, numParen = 0, quote, args;
|
||||
|
||||
var appendResult = function(){
|
||||
if(method) {
|
||||
if(definition.substr( 0, 1 ) === '"') {
|
||||
definition = definition.substr( 1, definition.length - 2 );
|
||||
var options = userOptions || {};
|
||||
|
||||
|
||||
this.opts = this.extendObj(options, {
|
||||
logging: false,
|
||||
ready: function (stack) {
|
||||
document.body.appendChild(stack.canvas);
|
||||
},
|
||||
storageReady: function(obj){
|
||||
obj.Renderer(obj.contextStacks);
|
||||
},
|
||||
iframeDefault: "default",
|
||||
flashCanvasPath: "http://html2canvas.hertzen.com/external/flashcanvas/flashcanvas.js",
|
||||
renderViewport: false,
|
||||
reorderZ: true,
|
||||
throttle:true,
|
||||
letterRendering:false,
|
||||
proxyUrl: null,
|
||||
logger: function(a){
|
||||
if (window.console && window.console.log){
|
||||
window.console.log(a);
|
||||
}else{
|
||||
alert(a);
|
||||
}
|
||||
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
|
||||
});
|
||||
}
|
||||
args = []; //for some odd reason, setting .length = 0 didn't work in safari
|
||||
method =
|
||||
prefix =
|
||||
definition =
|
||||
block = '';
|
||||
},
|
||||
canvasWidth:0,
|
||||
canvasHeight:0,
|
||||
useOverflow: true,
|
||||
renderOrder: "canvas flash html"
|
||||
});
|
||||
|
||||
this.element = el;
|
||||
|
||||
var imageLoaded,
|
||||
canvas,
|
||||
ctx,
|
||||
bgx,
|
||||
bgy,
|
||||
image;
|
||||
this.imagesLoaded = 0;
|
||||
this.images = [];
|
||||
this.fontData = [];
|
||||
this.numDraws = 0;
|
||||
this.contextStacks = [];
|
||||
this.ignoreElements = "IFRAME|OBJECT|PARAM";
|
||||
this.needReorder = false;
|
||||
this.blockElements = new RegExp("(BR|PARAM)");
|
||||
this.pageOrigin = window.location.protocol + window.location.host;
|
||||
this.queue = [];
|
||||
|
||||
this.ignoreRe = new RegExp("("+this.ignoreElements+")");
|
||||
|
||||
|
||||
this.support = {
|
||||
rangeBounds: false
|
||||
|
||||
};
|
||||
|
||||
// Test whether we can use ranges to measure bounding boxes
|
||||
// Opera doesn't provide valid bounds.height/bottom even though it supports the method.
|
||||
|
||||
appendResult();
|
||||
for(var i = 0, ii = value.length; i<ii; i++) {
|
||||
c = value[i];
|
||||
if(mode === 0 && whitespace.indexOf( c ) > -1){
|
||||
continue;
|
||||
}
|
||||
switch(c) {
|
||||
case '"':
|
||||
if(!quote) {
|
||||
quote = c;
|
||||
}
|
||||
else if(quote === c) {
|
||||
quote = null;
|
||||
}
|
||||
break;
|
||||
|
||||
if (document.createRange){
|
||||
var r = document.createRange();
|
||||
//this.support.rangeBounds = new Boolean(r.getBoundingClientRect);
|
||||
if (r.getBoundingClientRect){
|
||||
var testElement = document.createElement('boundtest');
|
||||
testElement.style.height = "123px";
|
||||
testElement.style.display = "block";
|
||||
document.getElementsByTagName('body')[0].appendChild(testElement);
|
||||
|
||||
r.selectNode(testElement);
|
||||
var rangeBounds = r.getBoundingClientRect();
|
||||
var rangeHeight = rangeBounds.height;
|
||||
|
||||
case '(':
|
||||
if(quote) { break; }
|
||||
else if(mode === 0) {
|
||||
mode = 1;
|
||||
block += c;
|
||||
continue;
|
||||
} else {
|
||||
numParen++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ')':
|
||||
if(quote) { break; }
|
||||
else if(mode === 1) {
|
||||
if(numParen === 0) {
|
||||
mode = 0;
|
||||
block += c;
|
||||
appendResult();
|
||||
continue;
|
||||
} else {
|
||||
numParen--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ',':
|
||||
if(quote) { break; }
|
||||
else if(mode === 0) {
|
||||
appendResult();
|
||||
continue;
|
||||
}
|
||||
else if (mode === 1) {
|
||||
if(numParen === 0 && !method.match(/^url$/i)) {
|
||||
args.push(definition);
|
||||
definition = '';
|
||||
block += c;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
block += c;
|
||||
if(mode === 0) { method += c; }
|
||||
else { definition += c; }
|
||||
}
|
||||
appendResult();
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
_html2canvas.Util.Bounds = function (element) {
|
||||
var clientRect, bounds = {};
|
||||
|
||||
if (element.getBoundingClientRect){
|
||||
clientRect = element.getBoundingClientRect();
|
||||
|
||||
// TODO add scroll position to bounds, so no scrolling of window necessary
|
||||
bounds.top = clientRect.top;
|
||||
bounds.bottom = clientRect.bottom || (clientRect.top + clientRect.height);
|
||||
bounds.left = clientRect.left;
|
||||
|
||||
bounds.width = element.offsetWidth;
|
||||
bounds.height = element.offsetHeight;
|
||||
}
|
||||
|
||||
return bounds;
|
||||
};
|
||||
|
||||
// TODO ideally, we'd want everything to go through this function instead of Util.Bounds,
|
||||
// but would require further work to calculate the correct positions for elements with offsetParents
|
||||
_html2canvas.Util.OffsetBounds = function (element) {
|
||||
var parent = element.offsetParent ? _html2canvas.Util.OffsetBounds(element.offsetParent) : {top: 0, left: 0};
|
||||
|
||||
return {
|
||||
top: element.offsetTop + parent.top,
|
||||
bottom: element.offsetTop + element.offsetHeight + parent.top,
|
||||
left: element.offsetLeft + parent.left,
|
||||
width: element.offsetWidth,
|
||||
height: element.offsetHeight
|
||||
};
|
||||
};
|
||||
|
||||
function toPX(element, attribute, value ) {
|
||||
var rsLeft = element.runtimeStyle && element.runtimeStyle[attribute],
|
||||
left,
|
||||
style = element.style;
|
||||
|
||||
// Check if we are not dealing with pixels, (Opera has issues with this)
|
||||
// Ported from jQuery css.js
|
||||
// From the awesome hack by Dean Edwards
|
||||
// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
|
||||
|
||||
// If we're not dealing with a regular pixel number
|
||||
// but a number that has a weird ending, we need to convert it to pixels
|
||||
|
||||
if ( !/^-?[0-9]+\.?[0-9]*(?:px)?$/i.test( value ) && /^-?\d/.test(value) ) {
|
||||
// Remember the original values
|
||||
left = style.left;
|
||||
|
||||
// Put in the new values to get a computed value out
|
||||
if (rsLeft) {
|
||||
element.runtimeStyle.left = element.currentStyle.left;
|
||||
}
|
||||
style.left = attribute === "fontSize" ? "1em" : (value || 0);
|
||||
value = style.pixelLeft + "px";
|
||||
|
||||
// Revert the changed values
|
||||
style.left = left;
|
||||
if (rsLeft) {
|
||||
element.runtimeStyle.left = rsLeft;
|
||||
}
|
||||
}
|
||||
|
||||
if (!/^(thin|medium|thick)$/i.test(value)) {
|
||||
return Math.round(parseFloat(value)) + "px";
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
function asInt(val) {
|
||||
return parseInt(val, 10);
|
||||
}
|
||||
|
||||
function parseBackgroundSizePosition(value, element, attribute, index) {
|
||||
value = (value || '').split(',');
|
||||
value = value[index || 0] || value[0] || 'auto';
|
||||
value = _html2canvas.Util.trimText(value).split(' ');
|
||||
|
||||
if(attribute === 'backgroundSize' && (!value[0] || value[0].match(/cover|contain|auto/))) {
|
||||
//these values will be handled in the parent function
|
||||
} else {
|
||||
value[0] = (value[0].indexOf( "%" ) === -1) ? toPX(element, attribute + "X", value[0]) : value[0];
|
||||
if(value[1] === undefined) {
|
||||
if(attribute === 'backgroundSize') {
|
||||
value[1] = 'auto';
|
||||
return value;
|
||||
} else {
|
||||
// IE 9 doesn't return double digit always
|
||||
value[1] = value[0];
|
||||
if (rangeHeight==123){
|
||||
this.support.rangeBounds = true;
|
||||
}
|
||||
document.getElementsByTagName('body')[0].removeChild(testElement);
|
||||
|
||||
|
||||
}
|
||||
value[1] = (value[1].indexOf("%") === -1) ? toPX(element, attribute + "Y", value[1]) : value[1];
|
||||
|
||||
}
|
||||
return value;
|
||||
|
||||
|
||||
|
||||
// Start script
|
||||
this.init();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
html2canvas.prototype.init = function(){
|
||||
|
||||
var _ = this;
|
||||
/*
|
||||
this.ctx = new this.stackingContext($(document).width(),$(document).height());
|
||||
|
||||
if (!this.ctx){
|
||||
// canvas not initialized, let's kill it here
|
||||
this.log('Canvas not available');
|
||||
return;
|
||||
}
|
||||
|
||||
this.canvas = this.ctx.canvas;
|
||||
*/
|
||||
this.log('Finding background-images');
|
||||
|
||||
this.images.push('start');
|
||||
|
||||
this.getImages(this.element);
|
||||
|
||||
this.log('Finding images');
|
||||
// console.log(this.element.ownerDocument);
|
||||
|
||||
|
||||
|
||||
this.each(this.element.ownerDocument.images,function(i,e){
|
||||
_.preloadImage(_.getAttr(e,'src'));
|
||||
});
|
||||
this.images.splice(0,1);
|
||||
// console.log(this.images);
|
||||
if (this.images.length == 0){
|
||||
this.start();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
_html2canvas.Util.getCSS = function (element, attribute, index) {
|
||||
if (previousElement !== element) {
|
||||
computedCSS = document.defaultView.getComputedStyle(element, null);
|
||||
/*
|
||||
* Check whether all assets have been loaded and start traversing the DOM
|
||||
*/
|
||||
|
||||
html2canvas.prototype.start = function(){
|
||||
// console.log(this.images);
|
||||
if (this.images.length == 0 || this.imagesLoaded==this.images.length/2){
|
||||
|
||||
this.log('Finished loading '+this.imagesLoaded+' images, Started parsing');
|
||||
this.bodyOverflow = document.getElementsByTagName('body')[0].style.overflow;
|
||||
document.getElementsByTagName('body')[0].style.overflow = "hidden";
|
||||
var rootStack = new this.storageContext($(document).width(),$(document).height());
|
||||
rootStack.opacity = this.getCSS(this.element,"opacity");
|
||||
var stack = this.newElement(this.element,rootStack);
|
||||
|
||||
|
||||
this.parseElement(this.element,stack);
|
||||
}
|
||||
|
||||
var value = computedCSS[attribute];
|
||||
|
||||
if (/^background(Size|Position)$/.test(attribute)) {
|
||||
return parseBackgroundSizePosition(value, element, attribute, index);
|
||||
} else if (/border(Top|Bottom)(Left|Right)Radius/.test(attribute)) {
|
||||
var arr = value.split(" ");
|
||||
if (arr.length <= 1) {
|
||||
arr[1] = arr[0];
|
||||
}
|
||||
return arr.map(asInt);
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
_html2canvas.Util.resizeBounds = function( current_width, current_height, target_width, target_height, stretch_mode ){
|
||||
var target_ratio = target_width / target_height,
|
||||
current_ratio = current_width / current_height,
|
||||
output_width, output_height;
|
||||
|
||||
if(!stretch_mode || stretch_mode === 'auto') {
|
||||
output_width = target_width;
|
||||
output_height = target_height;
|
||||
} else if(target_ratio < current_ratio ^ stretch_mode === 'contain') {
|
||||
output_height = target_height;
|
||||
output_width = target_height * current_ratio;
|
||||
} else {
|
||||
output_width = target_width;
|
||||
output_height = target_width / current_ratio;
|
||||
}
|
||||
|
||||
return {
|
||||
width: output_width,
|
||||
height: output_height
|
||||
};
|
||||
};
|
||||
|
||||
function backgroundBoundsFactory( prop, el, bounds, image, imageIndex, backgroundSize ) {
|
||||
var bgposition = _html2canvas.Util.getCSS( el, prop, imageIndex ) ,
|
||||
topPos,
|
||||
left,
|
||||
percentage,
|
||||
val;
|
||||
|
||||
if (bgposition.length === 1){
|
||||
val = bgposition[0];
|
||||
|
||||
bgposition = [];
|
||||
|
||||
bgposition[0] = val;
|
||||
bgposition[1] = val;
|
||||
}
|
||||
|
||||
if (bgposition[0].toString().indexOf("%") !== -1){
|
||||
percentage = (parseFloat(bgposition[0])/100);
|
||||
left = bounds.width * percentage;
|
||||
if(prop !== 'backgroundSize') {
|
||||
left -= (backgroundSize || image).width*percentage;
|
||||
}
|
||||
} else {
|
||||
if(prop === 'backgroundSize') {
|
||||
if(bgposition[0] === 'auto') {
|
||||
left = image.width;
|
||||
} else {
|
||||
if (/contain|cover/.test(bgposition[0])) {
|
||||
var resized = _html2canvas.Util.resizeBounds(image.width, image.height, bounds.width, bounds.height, bgposition[0]);
|
||||
left = resized.width;
|
||||
topPos = resized.height;
|
||||
} else {
|
||||
left = parseInt(bgposition[0], 10);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
left = parseInt( bgposition[0], 10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(bgposition[1] === 'auto') {
|
||||
topPos = left / image.width * image.height;
|
||||
} else if (bgposition[1].toString().indexOf("%") !== -1){
|
||||
percentage = (parseFloat(bgposition[1])/100);
|
||||
topPos = bounds.height * percentage;
|
||||
if(prop !== 'backgroundSize') {
|
||||
topPos -= (backgroundSize || image).height * percentage;
|
||||
}
|
||||
|
||||
} else {
|
||||
topPos = parseInt(bgposition[1],10);
|
||||
}
|
||||
|
||||
return [left, topPos];
|
||||
|
||||
}
|
||||
|
||||
_html2canvas.Util.BackgroundPosition = function( el, bounds, image, imageIndex, backgroundSize ) {
|
||||
var result = backgroundBoundsFactory( 'backgroundPosition', el, bounds, image, imageIndex, backgroundSize );
|
||||
return { left: result[0], top: result[1] };
|
||||
};
|
||||
|
||||
_html2canvas.Util.BackgroundSize = function( el, bounds, image, imageIndex ) {
|
||||
var result = backgroundBoundsFactory( 'backgroundSize', el, bounds, image, imageIndex );
|
||||
return { width: result[0], height: result[1] };
|
||||
};
|
||||
html2canvas.prototype.stackingContext = function(width,height){
|
||||
this.canvas = document.createElement('canvas');
|
||||
|
||||
|
||||
_html2canvas.Util.Extend = function (options, defaults) {
|
||||
for (var key in options) {
|
||||
if (options.hasOwnProperty(key)) {
|
||||
defaults[key] = options[key];
|
||||
}
|
||||
}
|
||||
return defaults;
|
||||
};
|
||||
this.canvas.width = width;
|
||||
this.canvas.height = width;
|
||||
|
||||
if (!this.canvas.getContext){
|
||||
|
||||
// TODO include Flashcanvas
|
||||
/*
|
||||
var script = document.createElement('script');
|
||||
script.type = "text/javascript";
|
||||
script.src = this.opts.flashCanvasPath;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(script, s);
|
||||
|
||||
if (typeof FlashCanvas != "undefined") {
|
||||
|
||||
FlashCanvas.initElement(this.canvas);
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
} */
|
||||
|
||||
}else{
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
}
|
||||
|
||||
// set common settings for canvas
|
||||
this.ctx.textBaseline = "bottom";
|
||||
|
||||
return this.ctx;
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.storageContext = function(width,height){
|
||||
this.storage = [];
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
//this.zIndex;
|
||||
|
||||
// todo simplify this whole section
|
||||
this.fillRect = function(x, y, w, h){
|
||||
this.storage.push(
|
||||
{
|
||||
type: "function",
|
||||
name:"fillRect",
|
||||
arguments:[x,y,w,h]
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.drawImage = function(image,sx,sy,sw,sh,dx,dy,dw,dh){
|
||||
this.storage.push(
|
||||
{
|
||||
type: "function",
|
||||
name:"drawImage",
|
||||
arguments:[image,sx,sy,sw,sh,dx,dy,dw,dh]
|
||||
});
|
||||
};
|
||||
|
||||
this.fillText = function(currentText,x,y){
|
||||
|
||||
this.storage.push(
|
||||
{
|
||||
type: "function",
|
||||
name:"fillText",
|
||||
arguments:[currentText,x,y]
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Derived from jQuery.contents()
|
||||
* Copyright 2010, John Resig
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*/
|
||||
_html2canvas.Util.Children = function( elem ) {
|
||||
var children;
|
||||
try {
|
||||
children = (elem.nodeName && elem.nodeName.toUpperCase() === "IFRAME") ? elem.contentDocument || elem.contentWindow.document : (function(array) {
|
||||
var ret = [];
|
||||
if (array !== null) {
|
||||
(function(first, second ) {
|
||||
var i = first.length,
|
||||
j = 0;
|
||||
* Finished rendering, send callback
|
||||
*/
|
||||
|
||||
if (typeof second.length === "number") {
|
||||
for (var l = second.length; j < l; j++) {
|
||||
first[i++] = second[j];
|
||||
}
|
||||
} else {
|
||||
while (second[j] !== undefined) {
|
||||
first[i++] = second[j++];
|
||||
}
|
||||
}
|
||||
html2canvas.prototype.finish = function(){
|
||||
|
||||
this.log("Finished rendering");
|
||||
|
||||
document.getElementsByTagName('body')[0].style.overflow = this.bodyOverflow;
|
||||
/*
|
||||
if (this.opts.renderViewport){
|
||||
// let's crop it to viewport only then
|
||||
var newCanvas = document.createElement('canvas');
|
||||
var newctx = newCanvas.getContext('2d');
|
||||
newCanvas.width = window.innerWidth;
|
||||
newCanvas.height = window.innerHeight;
|
||||
|
||||
}*/
|
||||
this.opts.ready(this);
|
||||
}
|
||||
|
||||
first.length = i;
|
||||
|
||||
return first;
|
||||
})(ret, array);
|
||||
}
|
||||
return ret;
|
||||
})(elem.childNodes);
|
||||
|
||||
} catch (ex) {
|
||||
_html2canvas.Util.log("html2canvas.Util.Children failed with exception: " + ex.message);
|
||||
children = [];
|
||||
}
|
||||
return children;
|
||||
};
|
||||
|
||||
_html2canvas.Util.isTransparent = function(backgroundColor) {
|
||||
return (backgroundColor === "transparent" || backgroundColor === "rgba(0, 0, 0, 0)");
|
||||
};
|
226
src/Draw.js
Normal file
@ -0,0 +1,226 @@
|
||||
html2canvas.prototype.newElement = function(el,parentStack){
|
||||
|
||||
var bounds = this.getBounds(el);
|
||||
|
||||
var x = bounds.left;
|
||||
var y = bounds.top;
|
||||
var w = bounds.width;
|
||||
var h = bounds.height;
|
||||
var _ = this,
|
||||
image;
|
||||
var bgcolor = this.getCSS(el,"background-color");
|
||||
|
||||
var cssPosition = this.getCSS(el,"position");
|
||||
parentStack = parentStack || {};
|
||||
|
||||
//var zindex = this.formatZ(this.getCSS(el,"zIndex"),cssPosition,parentStack.zIndex,el.parentNode);
|
||||
|
||||
var zindex = this.setZ(this.getCSS(el,"zIndex"),cssPosition,parentStack.zIndex,el.parentNode);
|
||||
|
||||
//console.log(el.nodeName+":"+zindex+":"+this.getCSS(el,"position")+":"+this.numDraws+":"+this.getCSS(el,"z-index"))
|
||||
|
||||
var opacity = this.getCSS(el,"opacity");
|
||||
|
||||
|
||||
var stack = {
|
||||
ctx: new this.storageContext(),
|
||||
zIndex: zindex,
|
||||
opacity: opacity*parentStack.opacity,
|
||||
cssPosition: cssPosition
|
||||
};
|
||||
|
||||
|
||||
|
||||
// TODO correct overflow for absolute content residing under a static position
|
||||
if (parentStack.clip){
|
||||
stack.clip = $.extend({}, parentStack.clip);
|
||||
//stack.clip = parentStack.clip;
|
||||
stack.clip.height = stack.clip.height - parentStack.borders[2].width;
|
||||
}
|
||||
|
||||
|
||||
if (this.opts.useOverflow && /(hidden|scroll|auto)/.test(this.getCSS(el,"overflow")) && !/(BODY)/i.test(el.nodeName)){
|
||||
if (stack.clip){
|
||||
stack.clip = this.clipBounds(stack.clip,bounds);
|
||||
}else{
|
||||
stack.clip = bounds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
var stackLength = this.contextStacks.push(stack);
|
||||
|
||||
var ctx = this.contextStacks[stackLength-1].ctx;
|
||||
*/
|
||||
|
||||
var stackLength = zindex.children.push(stack);
|
||||
|
||||
var ctx = zindex.children[stackLength-1].ctx;
|
||||
|
||||
this.setContextVariable(ctx,"globalAlpha",stack.opacity);
|
||||
|
||||
// draw element borders
|
||||
var borders = this.drawBorders(el, ctx, bounds);
|
||||
stack.borders = borders;
|
||||
|
||||
// let's modify clip area for child elements, so borders dont get overwritten
|
||||
|
||||
/*
|
||||
if (stack.clip){
|
||||
stack.clip.width = stack.clip.width-(borders[1].width);
|
||||
stack.clip.height = stack.clip.height-(borders[2].width);
|
||||
}
|
||||
*/
|
||||
if (this.ignoreRe.test(el.nodeName) && this.opts.iframeDefault != "transparent"){
|
||||
if (this.opts.iframeDefault=="default"){
|
||||
bgcolor = "#efefef";
|
||||
/*
|
||||
* TODO write X over frame
|
||||
*/
|
||||
}else{
|
||||
bgcolor = this.opts.iframeDefault;
|
||||
}
|
||||
}
|
||||
|
||||
// draw base element bgcolor
|
||||
|
||||
var bgbounds = {
|
||||
left: x+borders[3].width,
|
||||
top: y+borders[0].width,
|
||||
width: w-(borders[1].width+borders[3].width),
|
||||
height: h-(borders[0].width+borders[2].width)
|
||||
};
|
||||
|
||||
//if (this.withinBounds(stack.clip,bgbounds)){
|
||||
|
||||
if (stack.clip){
|
||||
bgbounds = this.clipBounds(bgbounds,stack.clip);
|
||||
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
if (bgbounds.height>0 && bgbounds.width>0){
|
||||
this.newRect(
|
||||
ctx,
|
||||
bgbounds.left,
|
||||
bgbounds.top,
|
||||
bgbounds.width,
|
||||
bgbounds.height,
|
||||
bgcolor
|
||||
);
|
||||
|
||||
this.drawBackground(el,bgbounds,ctx);
|
||||
}
|
||||
|
||||
switch(el.nodeName){
|
||||
case "IMG":
|
||||
image = _.loadImage(_.getAttr(el,'src'));
|
||||
if (image){
|
||||
// console.log(image.width);
|
||||
this.drawImage(
|
||||
ctx,
|
||||
image,
|
||||
0, //sx
|
||||
0, //sy
|
||||
image.width, //sw
|
||||
image.height, //sh
|
||||
x+parseInt(_.getCSS(el,'padding-left'),10) + borders[3].width, //dx
|
||||
y+parseInt(_.getCSS(el,'padding-top'),10) + borders[0].width, // dy
|
||||
bounds.width - (borders[1].width + borders[3].width + parseInt(_.getCSS(el,'padding-left'),10) + parseInt(_.getCSS(el,'padding-right'),10)), //dw
|
||||
bounds.height - (borders[0].width + borders[2].width + parseInt(_.getCSS(el,'padding-top'),10) + parseInt(_.getCSS(el,'padding-bottom'),10)) //dh
|
||||
);
|
||||
|
||||
}else {
|
||||
this.log("Error loading <img>:" + _.getAttr(el,'src'));
|
||||
}
|
||||
break;
|
||||
case "INPUT":
|
||||
// TODO add all relevant type's, i.e. HTML5 new stuff
|
||||
// todo add support for placeholder attribute for browsers which support it
|
||||
if (/^(text|url|email|submit|button|reset)$/.test(el.type) && el.value.length > 0){
|
||||
|
||||
this.renderFormValue(el,bounds,stack);
|
||||
|
||||
|
||||
/*
|
||||
this just doesn't work well enough
|
||||
|
||||
this.newText(el,{
|
||||
nodeValue:el.value,
|
||||
splitText: function(){
|
||||
return this;
|
||||
},
|
||||
formValue:true
|
||||
},stack);
|
||||
*/
|
||||
}
|
||||
break;
|
||||
case "TEXTAREA":
|
||||
if (el.value.length > 0){
|
||||
this.renderFormValue(el,bounds,stack);
|
||||
}
|
||||
break;
|
||||
case "SELECT":
|
||||
if (el.options.length > 0){
|
||||
this.renderFormValue(el,bounds,stack);
|
||||
}
|
||||
break;
|
||||
case "LI":
|
||||
this.drawListItem(el,stack,bgbounds);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// return this.contextStacks[stackLength-1];
|
||||
return zindex.children[stackLength-1];
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Function to draw the text on the canvas
|
||||
*/
|
||||
|
||||
html2canvas.prototype.printText = function(currentText,x,y,ctx){
|
||||
if (this.trim(currentText).length>0){
|
||||
|
||||
ctx.fillText(currentText,x,y);
|
||||
this.numDraws++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Drawing a rectangle
|
||||
html2canvas.prototype.newRect = function(ctx,x,y,w,h,bgcolor){
|
||||
|
||||
if (bgcolor!="transparent"){
|
||||
this.setContextVariable(ctx,"fillStyle",bgcolor);
|
||||
ctx.fillRect (x, y, w, h);
|
||||
this.numDraws++;
|
||||
}
|
||||
}
|
||||
|
||||
html2canvas.prototype.drawImage = function(ctx,image,sx,sy,sw,sh,dx,dy,dw,dh){
|
||||
ctx.drawImage(
|
||||
image,
|
||||
sx, //sx
|
||||
sy, //sy
|
||||
sw, //sw
|
||||
sh, //sh
|
||||
dx, //dx
|
||||
dy, // dy
|
||||
dw, //dw
|
||||
dh //dh
|
||||
);
|
||||
this.numDraws++;
|
||||
|
||||
}
|
64
src/Font.js
@ -1,64 +0,0 @@
|
||||
_html2canvas.Util.Font = (function () {
|
||||
|
||||
var fontData = {};
|
||||
|
||||
return function(font, fontSize, doc) {
|
||||
if (fontData[font + "-" + fontSize] !== undefined) {
|
||||
return fontData[font + "-" + fontSize];
|
||||
}
|
||||
|
||||
var container = doc.createElement('div'),
|
||||
img = doc.createElement('img'),
|
||||
span = doc.createElement('span'),
|
||||
sampleText = 'Hidden Text',
|
||||
baseline,
|
||||
middle,
|
||||
metricsObj;
|
||||
|
||||
container.style.visibility = "hidden";
|
||||
container.style.fontFamily = font;
|
||||
container.style.fontSize = fontSize;
|
||||
container.style.margin = 0;
|
||||
container.style.padding = 0;
|
||||
|
||||
doc.body.appendChild(container);
|
||||
|
||||
// http://probablyprogramming.com/2009/03/15/the-tiniest-gif-ever (handtinywhite.gif)
|
||||
img.src = "data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACwAAAAAAQABAAACAkQBADs=";
|
||||
img.width = 1;
|
||||
img.height = 1;
|
||||
|
||||
img.style.margin = 0;
|
||||
img.style.padding = 0;
|
||||
img.style.verticalAlign = "baseline";
|
||||
|
||||
span.style.fontFamily = font;
|
||||
span.style.fontSize = fontSize;
|
||||
span.style.margin = 0;
|
||||
span.style.padding = 0;
|
||||
|
||||
span.appendChild(doc.createTextNode(sampleText));
|
||||
container.appendChild(span);
|
||||
container.appendChild(img);
|
||||
baseline = (img.offsetTop - span.offsetTop) + 1;
|
||||
|
||||
container.removeChild(span);
|
||||
container.appendChild(doc.createTextNode(sampleText));
|
||||
|
||||
container.style.lineHeight = "normal";
|
||||
img.style.verticalAlign = "super";
|
||||
|
||||
middle = (img.offsetTop-container.offsetTop) + 1;
|
||||
metricsObj = {
|
||||
baseline: baseline,
|
||||
lineWidth: 1,
|
||||
middle: middle
|
||||
};
|
||||
|
||||
fontData[font + "-" + fontSize] = metricsObj;
|
||||
|
||||
doc.body.removeChild(container);
|
||||
|
||||
return metricsObj;
|
||||
};
|
||||
})();
|
38
src/Forms.js
Normal file
@ -0,0 +1,38 @@
|
||||
html2canvas.prototype.renderFormValue = function(el,bounds,stack){
|
||||
|
||||
var valueWrap = document.createElement('valuewrap'),
|
||||
_ = this;
|
||||
|
||||
this.each(['lineHeight','textAlign','fontFamily','color','fontSize','paddingLeft','paddingTop','width','height','border','borderLeftWidth','borderTopWidth'],function(i,style){
|
||||
valueWrap.style[style] = _.getCSS(el,style);
|
||||
});
|
||||
|
||||
valueWrap.style.borderColor = "black";
|
||||
valueWrap.style.borderStyle = "solid";
|
||||
valueWrap.style.display = "block";
|
||||
valueWrap.style.position = "absolute";
|
||||
if (/^(submit|reset|button|text|password)$/.test(el.type) || el.nodeName == "SELECT"){
|
||||
valueWrap.style.lineHeight = _.getCSS(el,"height");
|
||||
}
|
||||
|
||||
|
||||
valueWrap.style.top = bounds.top+"px";
|
||||
valueWrap.style.left = bounds.left+"px";
|
||||
if (el.nodeName == "SELECT"){
|
||||
// TODO increase accuracy of text position
|
||||
var textValue = el.options[el.selectedIndex].text;
|
||||
} else{
|
||||
var textValue = el.value;
|
||||
|
||||
}
|
||||
var textNode = document.createTextNode(textValue);
|
||||
|
||||
valueWrap.appendChild(textNode);
|
||||
$('body').append(valueWrap);
|
||||
|
||||
this.newText(el,textNode,stack);
|
||||
|
||||
$(valueWrap).remove();
|
||||
|
||||
|
||||
}
|
424
src/Generate.js
@ -1,424 +0,0 @@
|
||||
(function(){
|
||||
var Util = _html2canvas.Util,
|
||||
Generate = {};
|
||||
|
||||
_html2canvas.Generate = Generate;
|
||||
|
||||
var reGradients = [
|
||||
/^(-webkit-linear-gradient)\(([a-z\s]+)([\w\d\.\s,%\(\)]+)\)$/,
|
||||
/^(-o-linear-gradient)\(([a-z\s]+)([\w\d\.\s,%\(\)]+)\)$/,
|
||||
/^(-webkit-gradient)\((linear|radial),\s((?:\d{1,3}%?)\s(?:\d{1,3}%?),\s(?:\d{1,3}%?)\s(?:\d{1,3}%?))([\w\d\.\s,%\(\)\-]+)\)$/,
|
||||
/^(-moz-linear-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?))([\w\d\.\s,%\(\)]+)\)$/,
|
||||
/^(-webkit-radial-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?)),\s(\w+)\s([a-z\-]+)([\w\d\.\s,%\(\)]+)\)$/,
|
||||
/^(-moz-radial-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?)),\s(\w+)\s?([a-z\-]*)([\w\d\.\s,%\(\)]+)\)$/,
|
||||
/^(-o-radial-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?)),\s(\w+)\s([a-z\-]+)([\w\d\.\s,%\(\)]+)\)$/
|
||||
];
|
||||
|
||||
/*
|
||||
* TODO: Add IE10 vendor prefix (-ms) support
|
||||
* TODO: Add W3C gradient (linear-gradient) support
|
||||
* TODO: Add old Webkit -webkit-gradient(radial, ...) support
|
||||
* TODO: Maybe some RegExp optimizations are possible ;o)
|
||||
*/
|
||||
Generate.parseGradient = function(css, bounds) {
|
||||
var gradient, i, len = reGradients.length, m1, stop, m2, m2Len, step, m3, tl,tr,br,bl;
|
||||
|
||||
for(i = 0; i < len; i+=1){
|
||||
m1 = css.match(reGradients[i]);
|
||||
if(m1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(m1) {
|
||||
switch(m1[1]) {
|
||||
case '-webkit-linear-gradient':
|
||||
case '-o-linear-gradient':
|
||||
|
||||
gradient = {
|
||||
type: 'linear',
|
||||
x0: null,
|
||||
y0: null,
|
||||
x1: null,
|
||||
y1: null,
|
||||
colorStops: []
|
||||
};
|
||||
|
||||
// get coordinates
|
||||
m2 = m1[2].match(/\w+/g);
|
||||
if(m2){
|
||||
m2Len = m2.length;
|
||||
for(i = 0; i < m2Len; i+=1){
|
||||
switch(m2[i]) {
|
||||
case 'top':
|
||||
gradient.y0 = 0;
|
||||
gradient.y1 = bounds.height;
|
||||
break;
|
||||
|
||||
case 'right':
|
||||
gradient.x0 = bounds.width;
|
||||
gradient.x1 = 0;
|
||||
break;
|
||||
|
||||
case 'bottom':
|
||||
gradient.y0 = bounds.height;
|
||||
gradient.y1 = 0;
|
||||
break;
|
||||
|
||||
case 'left':
|
||||
gradient.x0 = 0;
|
||||
gradient.x1 = bounds.width;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(gradient.x0 === null && gradient.x1 === null){ // center
|
||||
gradient.x0 = gradient.x1 = bounds.width / 2;
|
||||
}
|
||||
if(gradient.y0 === null && gradient.y1 === null){ // center
|
||||
gradient.y0 = gradient.y1 = bounds.height / 2;
|
||||
}
|
||||
|
||||
// get colors and stops
|
||||
m2 = m1[3].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)(?:\s\d{1,3}(?:%|px))?)+/g);
|
||||
if(m2){
|
||||
m2Len = m2.length;
|
||||
step = 1 / Math.max(m2Len - 1, 1);
|
||||
for(i = 0; i < m2Len; i+=1){
|
||||
m3 = m2[i].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/);
|
||||
if(m3[2]){
|
||||
stop = parseFloat(m3[2]);
|
||||
if(m3[3] === '%'){
|
||||
stop /= 100;
|
||||
} else { // px - stupid opera
|
||||
stop /= bounds.width;
|
||||
}
|
||||
} else {
|
||||
stop = i * step;
|
||||
}
|
||||
gradient.colorStops.push({
|
||||
color: m3[1],
|
||||
stop: stop
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '-webkit-gradient':
|
||||
|
||||
gradient = {
|
||||
type: m1[2] === 'radial' ? 'circle' : m1[2], // TODO: Add radial gradient support for older mozilla definitions
|
||||
x0: 0,
|
||||
y0: 0,
|
||||
x1: 0,
|
||||
y1: 0,
|
||||
colorStops: []
|
||||
};
|
||||
|
||||
// get coordinates
|
||||
m2 = m1[3].match(/(\d{1,3})%?\s(\d{1,3})%?,\s(\d{1,3})%?\s(\d{1,3})%?/);
|
||||
if(m2){
|
||||
gradient.x0 = (m2[1] * bounds.width) / 100;
|
||||
gradient.y0 = (m2[2] * bounds.height) / 100;
|
||||
gradient.x1 = (m2[3] * bounds.width) / 100;
|
||||
gradient.y1 = (m2[4] * bounds.height) / 100;
|
||||
}
|
||||
|
||||
// get colors and stops
|
||||
m2 = m1[4].match(/((?:from|to|color-stop)\((?:[0-9\.]+,\s)?(?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)\))+/g);
|
||||
if(m2){
|
||||
m2Len = m2.length;
|
||||
for(i = 0; i < m2Len; i+=1){
|
||||
m3 = m2[i].match(/(from|to|color-stop)\(([0-9\.]+)?(?:,\s)?((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\)/);
|
||||
stop = parseFloat(m3[2]);
|
||||
if(m3[1] === 'from') {
|
||||
stop = 0.0;
|
||||
}
|
||||
if(m3[1] === 'to') {
|
||||
stop = 1.0;
|
||||
}
|
||||
gradient.colorStops.push({
|
||||
color: m3[3],
|
||||
stop: stop
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '-moz-linear-gradient':
|
||||
|
||||
gradient = {
|
||||
type: 'linear',
|
||||
x0: 0,
|
||||
y0: 0,
|
||||
x1: 0,
|
||||
y1: 0,
|
||||
colorStops: []
|
||||
};
|
||||
|
||||
// get coordinates
|
||||
m2 = m1[2].match(/(\d{1,3})%?\s(\d{1,3})%?/);
|
||||
|
||||
// m2[1] == 0% -> left
|
||||
// m2[1] == 50% -> center
|
||||
// m2[1] == 100% -> right
|
||||
|
||||
// m2[2] == 0% -> top
|
||||
// m2[2] == 50% -> center
|
||||
// m2[2] == 100% -> bottom
|
||||
|
||||
if(m2){
|
||||
gradient.x0 = (m2[1] * bounds.width) / 100;
|
||||
gradient.y0 = (m2[2] * bounds.height) / 100;
|
||||
gradient.x1 = bounds.width - gradient.x0;
|
||||
gradient.y1 = bounds.height - gradient.y0;
|
||||
}
|
||||
|
||||
// get colors and stops
|
||||
m2 = m1[3].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)(?:\s\d{1,3}%)?)+/g);
|
||||
if(m2){
|
||||
m2Len = m2.length;
|
||||
step = 1 / Math.max(m2Len - 1, 1);
|
||||
for(i = 0; i < m2Len; i+=1){
|
||||
m3 = m2[i].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%)?/);
|
||||
if(m3[2]){
|
||||
stop = parseFloat(m3[2]);
|
||||
if(m3[3]){ // percentage
|
||||
stop /= 100;
|
||||
}
|
||||
} else {
|
||||
stop = i * step;
|
||||
}
|
||||
gradient.colorStops.push({
|
||||
color: m3[1],
|
||||
stop: stop
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case '-webkit-radial-gradient':
|
||||
case '-moz-radial-gradient':
|
||||
case '-o-radial-gradient':
|
||||
|
||||
gradient = {
|
||||
type: 'circle',
|
||||
x0: 0,
|
||||
y0: 0,
|
||||
x1: bounds.width,
|
||||
y1: bounds.height,
|
||||
cx: 0,
|
||||
cy: 0,
|
||||
rx: 0,
|
||||
ry: 0,
|
||||
colorStops: []
|
||||
};
|
||||
|
||||
// center
|
||||
m2 = m1[2].match(/(\d{1,3})%?\s(\d{1,3})%?/);
|
||||
if(m2){
|
||||
gradient.cx = (m2[1] * bounds.width) / 100;
|
||||
gradient.cy = (m2[2] * bounds.height) / 100;
|
||||
}
|
||||
|
||||
// size
|
||||
m2 = m1[3].match(/\w+/);
|
||||
m3 = m1[4].match(/[a-z\-]*/);
|
||||
if(m2 && m3){
|
||||
switch(m3[0]){
|
||||
case 'farthest-corner':
|
||||
case 'cover': // is equivalent to farthest-corner
|
||||
case '': // mozilla removes "cover" from definition :(
|
||||
tl = Math.sqrt(Math.pow(gradient.cx, 2) + Math.pow(gradient.cy, 2));
|
||||
tr = Math.sqrt(Math.pow(gradient.cx, 2) + Math.pow(gradient.y1 - gradient.cy, 2));
|
||||
br = Math.sqrt(Math.pow(gradient.x1 - gradient.cx, 2) + Math.pow(gradient.y1 - gradient.cy, 2));
|
||||
bl = Math.sqrt(Math.pow(gradient.x1 - gradient.cx, 2) + Math.pow(gradient.cy, 2));
|
||||
gradient.rx = gradient.ry = Math.max(tl, tr, br, bl);
|
||||
break;
|
||||
case 'closest-corner':
|
||||
tl = Math.sqrt(Math.pow(gradient.cx, 2) + Math.pow(gradient.cy, 2));
|
||||
tr = Math.sqrt(Math.pow(gradient.cx, 2) + Math.pow(gradient.y1 - gradient.cy, 2));
|
||||
br = Math.sqrt(Math.pow(gradient.x1 - gradient.cx, 2) + Math.pow(gradient.y1 - gradient.cy, 2));
|
||||
bl = Math.sqrt(Math.pow(gradient.x1 - gradient.cx, 2) + Math.pow(gradient.cy, 2));
|
||||
gradient.rx = gradient.ry = Math.min(tl, tr, br, bl);
|
||||
break;
|
||||
case 'farthest-side':
|
||||
if(m2[0] === 'circle'){
|
||||
gradient.rx = gradient.ry = Math.max(
|
||||
gradient.cx,
|
||||
gradient.cy,
|
||||
gradient.x1 - gradient.cx,
|
||||
gradient.y1 - gradient.cy
|
||||
);
|
||||
} else { // ellipse
|
||||
|
||||
gradient.type = m2[0];
|
||||
|
||||
gradient.rx = Math.max(
|
||||
gradient.cx,
|
||||
gradient.x1 - gradient.cx
|
||||
);
|
||||
gradient.ry = Math.max(
|
||||
gradient.cy,
|
||||
gradient.y1 - gradient.cy
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'closest-side':
|
||||
case 'contain': // is equivalent to closest-side
|
||||
if(m2[0] === 'circle'){
|
||||
gradient.rx = gradient.ry = Math.min(
|
||||
gradient.cx,
|
||||
gradient.cy,
|
||||
gradient.x1 - gradient.cx,
|
||||
gradient.y1 - gradient.cy
|
||||
);
|
||||
} else { // ellipse
|
||||
|
||||
gradient.type = m2[0];
|
||||
|
||||
gradient.rx = Math.min(
|
||||
gradient.cx,
|
||||
gradient.x1 - gradient.cx
|
||||
);
|
||||
gradient.ry = Math.min(
|
||||
gradient.cy,
|
||||
gradient.y1 - gradient.cy
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
// TODO: add support for "30px 40px" sizes (webkit only)
|
||||
}
|
||||
}
|
||||
|
||||
// color stops
|
||||
m2 = m1[5].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)(?:\s\d{1,3}(?:%|px))?)+/g);
|
||||
if(m2){
|
||||
m2Len = m2.length;
|
||||
step = 1 / Math.max(m2Len - 1, 1);
|
||||
for(i = 0; i < m2Len; i+=1){
|
||||
m3 = m2[i].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/);
|
||||
if(m3[2]){
|
||||
stop = parseFloat(m3[2]);
|
||||
if(m3[3] === '%'){
|
||||
stop /= 100;
|
||||
} else { // px - stupid opera
|
||||
stop /= bounds.width;
|
||||
}
|
||||
} else {
|
||||
stop = i * step;
|
||||
}
|
||||
gradient.colorStops.push({
|
||||
color: m3[1],
|
||||
stop: stop
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return gradient;
|
||||
};
|
||||
|
||||
function addScrollStops(grad) {
|
||||
return function(colorStop) {
|
||||
try {
|
||||
grad.addColorStop(colorStop.stop, colorStop.color);
|
||||
}
|
||||
catch(e) {
|
||||
Util.log(['failed to add color stop: ', e, '; tried to add: ', colorStop]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Generate.Gradient = function(src, bounds) {
|
||||
if(bounds.width === 0 || bounds.height === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var canvas = document.createElement('canvas'),
|
||||
ctx = canvas.getContext('2d'),
|
||||
gradient, grad;
|
||||
|
||||
canvas.width = bounds.width;
|
||||
canvas.height = bounds.height;
|
||||
|
||||
// TODO: add support for multi defined background gradients
|
||||
gradient = _html2canvas.Generate.parseGradient(src, bounds);
|
||||
|
||||
if(gradient) {
|
||||
switch(gradient.type) {
|
||||
case 'linear':
|
||||
grad = ctx.createLinearGradient(gradient.x0, gradient.y0, gradient.x1, gradient.y1);
|
||||
gradient.colorStops.forEach(addScrollStops(grad));
|
||||
ctx.fillStyle = grad;
|
||||
ctx.fillRect(0, 0, bounds.width, bounds.height);
|
||||
break;
|
||||
|
||||
case 'circle':
|
||||
grad = ctx.createRadialGradient(gradient.cx, gradient.cy, 0, gradient.cx, gradient.cy, gradient.rx);
|
||||
gradient.colorStops.forEach(addScrollStops(grad));
|
||||
ctx.fillStyle = grad;
|
||||
ctx.fillRect(0, 0, bounds.width, bounds.height);
|
||||
break;
|
||||
|
||||
case 'ellipse':
|
||||
var canvasRadial = document.createElement('canvas'),
|
||||
ctxRadial = canvasRadial.getContext('2d'),
|
||||
ri = Math.max(gradient.rx, gradient.ry),
|
||||
di = ri * 2;
|
||||
|
||||
canvasRadial.width = canvasRadial.height = di;
|
||||
|
||||
grad = ctxRadial.createRadialGradient(gradient.rx, gradient.ry, 0, gradient.rx, gradient.ry, ri);
|
||||
gradient.colorStops.forEach(addScrollStops(grad));
|
||||
|
||||
ctxRadial.fillStyle = grad;
|
||||
ctxRadial.fillRect(0, 0, di, di);
|
||||
|
||||
ctx.fillStyle = gradient.colorStops[gradient.colorStops.length - 1].color;
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.drawImage(canvasRadial, gradient.cx - gradient.rx, gradient.cy - gradient.ry, 2 * gradient.rx, 2 * gradient.ry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return canvas;
|
||||
};
|
||||
|
||||
Generate.ListAlpha = function(number) {
|
||||
var tmp = "",
|
||||
modulus;
|
||||
|
||||
do {
|
||||
modulus = number % 26;
|
||||
tmp = String.fromCharCode((modulus) + 64) + tmp;
|
||||
number = number / 26;
|
||||
}while((number*26) > 26);
|
||||
|
||||
return tmp;
|
||||
};
|
||||
|
||||
Generate.ListRoman = function(number) {
|
||||
var romanArray = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"],
|
||||
decimal = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1],
|
||||
roman = "",
|
||||
v,
|
||||
len = romanArray.length;
|
||||
|
||||
if (number <= 0 || number >= 4000) {
|
||||
return number;
|
||||
}
|
||||
|
||||
for (v=0; v < len; v+=1) {
|
||||
while (number >= decimal[v]) {
|
||||
number -= decimal[v];
|
||||
roman += romanArray[v];
|
||||
}
|
||||
}
|
||||
|
||||
return roman;
|
||||
};
|
||||
})();
|
129
src/Images.js
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Function to find all images from <img> and background-image
|
||||
*/
|
||||
html2canvas.prototype.getImages = function(el) {
|
||||
|
||||
var self = this;
|
||||
|
||||
if (!this.ignoreRe.test(el.nodeName)){
|
||||
// TODO remove jQuery dependancy
|
||||
this.each($(el).contents(),function(i,element){
|
||||
var ignRe = new RegExp("("+this.ignoreElements+")");
|
||||
if (!ignRe.test(element.nodeName)){
|
||||
self.getImages(element);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (el.nodeType==1 || typeof el.nodeType == "undefined"){
|
||||
var background_image = this.getCSS(el,'background-image');
|
||||
|
||||
if (background_image && background_image != "1" && background_image != "none" && background_image.substring(0,7)!="-webkit" && background_image.substring(0,3)!="-o-" && background_image.substring(0,4)!="-moz"){
|
||||
// TODO add multi image background support
|
||||
var src = this.backgroundImageUrl(background_image.split(",")[0]);
|
||||
this.preloadImage(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Load image from storage
|
||||
*/
|
||||
|
||||
html2canvas.prototype.loadImage = function(src){
|
||||
|
||||
var imgIndex = this.getIndex(this.images,src);
|
||||
if (imgIndex!=-1){
|
||||
return this.images[imgIndex+1];
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
html2canvas.prototype.preloadImage = function(src){
|
||||
|
||||
|
||||
if (this.getIndex(this.images,src)==-1){
|
||||
if (this.isSameOrigin(src)){
|
||||
this.images.push(src);
|
||||
// console.log('a'+src);
|
||||
var img = new Image();
|
||||
// TODO remove jQuery dependancy
|
||||
var _ = this;
|
||||
$(img).load(function(){
|
||||
_.imagesLoaded++;
|
||||
_.start();
|
||||
|
||||
});
|
||||
img.onerror = function(){
|
||||
_.images.splice(_.images.indexOf(img.src),2);
|
||||
// _.imagesLoaded++;
|
||||
_.start();
|
||||
}
|
||||
img.src = src;
|
||||
this.images.push(img);
|
||||
}else if (this.opts.proxyUrl){
|
||||
// console.log('b'+src);
|
||||
this.images.push(src);
|
||||
var img = new Image();
|
||||
this.proxyGetImage(src,img);
|
||||
this.images.push(img);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.proxyGetImage = function(url,img){
|
||||
var _ = this;
|
||||
|
||||
var link = document.createElement("a");
|
||||
link.href = url;
|
||||
url = link.href; // work around for pages with base href="" set
|
||||
|
||||
|
||||
// todo remove jQuery dependency and enable xhr2 requests where available (no need for base64 / json)
|
||||
$.ajax({
|
||||
data:{
|
||||
xhr2:false,
|
||||
url:url
|
||||
},
|
||||
url: this.opts.proxyUrl,
|
||||
dataType: "jsonp",
|
||||
success: function(a){
|
||||
|
||||
if (a.substring(0,6)=="error:"){
|
||||
_.images.splice(_.images.indexOf(url),2);
|
||||
_.start();
|
||||
_.log('Proxy was unable to load '+url+' '+a);
|
||||
}else{
|
||||
// document.createElement(a);
|
||||
// console.log(img);
|
||||
img.onload = function(){
|
||||
// console.log('w'+img.width);
|
||||
_.imagesLoaded++;
|
||||
_.start();
|
||||
|
||||
}
|
||||
|
||||
img.src = a;
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
error: function(){
|
||||
|
||||
_.images.splice(_.images.indexOf(url),2);
|
||||
// _.imagesLoaded++;
|
||||
_.start();
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
7
src/LICENSE
Normal file
@ -0,0 +1,7 @@
|
||||
/*
|
||||
* html2canvas v0.27 <http://html2canvas.hertzen.com>
|
||||
* Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
* http://www.twitter.com/niklasvh
|
||||
*
|
||||
* Released under MIT License
|
||||
*/
|
121
src/Lists.js
Normal file
@ -0,0 +1,121 @@
|
||||
html2canvas.prototype.drawListItem = function(element,stack,elBounds){
|
||||
|
||||
|
||||
var position = this.getCSS(element,"list-style-position",false);
|
||||
|
||||
|
||||
var item = this.getListItem(element),
|
||||
x,
|
||||
y;
|
||||
|
||||
var type = this.getCSS(element,"list-style-type",false);
|
||||
|
||||
if (/^(decimal|decimal-leading-zero|upper-alpha|upper-latin|upper-roman|lower-alpha|lower-greek|lower-latin|lower-roman)$/i.test(type)){
|
||||
// TODO remove jQuery dependency
|
||||
var currentIndex = $(element).index()+1,
|
||||
text;
|
||||
|
||||
if (type == "decimal"){
|
||||
text = currentIndex;
|
||||
}else if (type == "decimal-leading-zero"){
|
||||
if (currentIndex.toString().length == 1){
|
||||
text = currentIndex = "0" + currentIndex.toString();
|
||||
}else{
|
||||
text = currentIndex.toString();
|
||||
}
|
||||
|
||||
}else if (type == "upper-roman"){
|
||||
text = this.getListRoman(currentIndex);
|
||||
}else if (type == "lower-roman"){
|
||||
text = this.getListRoman(currentIndex).toLowerCase();
|
||||
}else if (type == "lower-alpha"){
|
||||
text = this.getListAlpha(currentIndex).toLowerCase();
|
||||
}else if (type == "upper-alpha"){
|
||||
text = this.getListAlpha(currentIndex);
|
||||
}
|
||||
|
||||
text += ". ";
|
||||
var listBounds = this.getListPosition(element,text);
|
||||
|
||||
if (position == "inside"){
|
||||
this.setFont(stack.ctx,element,false);
|
||||
x = elBounds.left;
|
||||
}else{
|
||||
return; /* TODO really need to figure out some more accurate way to try and find the position.
|
||||
as defined in http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position, it does not even have a specified "correct" position, so each browser
|
||||
may display it whatever way it feels like.
|
||||
"The position of the list-item marker adjacent to floats is undefined in CSS 2.1. CSS 2.1 does not specify the precise location of the marker box or its position in the painting order"
|
||||
*/
|
||||
this.setFont(stack.ctx,element,true);
|
||||
x = elBounds.left-10;
|
||||
}
|
||||
|
||||
y = listBounds.bottom;
|
||||
|
||||
|
||||
this.printText(text, x, y, stack.ctx);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.getListPosition = function(element,val){
|
||||
var boundElement = document.createElement("boundelement");
|
||||
boundElement.style.display = "inline";
|
||||
//boundElement.style.width = "1px";
|
||||
//boundElement.style.height = "1px";
|
||||
|
||||
var type = element.style.listStyleType;
|
||||
element.style.listStyleType = "none";
|
||||
|
||||
boundElement.appendChild(document.createTextNode(val));
|
||||
|
||||
|
||||
element.insertBefore(boundElement,element.firstChild);
|
||||
|
||||
|
||||
var bounds = this.getBounds(boundElement);
|
||||
element.removeChild(boundElement);
|
||||
element.style.listStyleType = type;
|
||||
return bounds;
|
||||
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.getListItem = function(element){
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
html2canvas.prototype.getListAlpha = function(number){
|
||||
var tmp = "";
|
||||
do{
|
||||
var modulus = number % 26;
|
||||
tmp = String.fromCharCode((modulus) + 64) + tmp;
|
||||
number = number / 26;
|
||||
}while((number*26) > 26);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
html2canvas.prototype.getListRoman = function(number){
|
||||
var romanArray = ["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"],
|
||||
decimal = [1000,900,500,400,100,90,50,40,10,9,5,4,1],
|
||||
roman = "";
|
||||
|
||||
if (number <= 0 || number >= 4000) return;
|
||||
for (var v=0; v<romanArray.length; v++) {
|
||||
while (number >= decimal[v]) {
|
||||
number -= decimal[v];
|
||||
roman += romanArray[v];
|
||||
}
|
||||
}
|
||||
|
||||
return roman;
|
||||
|
||||
|
||||
}
|
1143
src/Parse.js
317
src/Preload.js
@ -1,317 +0,0 @@
|
||||
_html2canvas.Preload = function( options ) {
|
||||
|
||||
var images = {
|
||||
numLoaded: 0, // also failed are counted here
|
||||
numFailed: 0,
|
||||
numTotal: 0,
|
||||
cleanupDone: false
|
||||
},
|
||||
pageOrigin,
|
||||
Util = _html2canvas.Util,
|
||||
methods,
|
||||
i,
|
||||
count = 0,
|
||||
element = options.elements[0] || document.body,
|
||||
doc = element.ownerDocument,
|
||||
domImages = element.getElementsByTagName('img'), // Fetch images of the present element only
|
||||
imgLen = domImages.length,
|
||||
link = doc.createElement("a"),
|
||||
supportCORS = (function( img ){
|
||||
return (img.crossOrigin !== undefined);
|
||||
})(new Image()),
|
||||
timeoutTimer;
|
||||
|
||||
link.href = window.location.href;
|
||||
pageOrigin = link.protocol + link.host;
|
||||
|
||||
function isSameOrigin(url){
|
||||
link.href = url;
|
||||
link.href = link.href; // YES, BELIEVE IT OR NOT, that is required for IE9 - http://jsfiddle.net/niklasvh/2e48b/
|
||||
var origin = link.protocol + link.host;
|
||||
return (origin === pageOrigin);
|
||||
}
|
||||
|
||||
function start(){
|
||||
Util.log("html2canvas: start: images: " + images.numLoaded + " / " + images.numTotal + " (failed: " + images.numFailed + ")");
|
||||
if (!images.firstRun && images.numLoaded >= images.numTotal){
|
||||
Util.log("Finished loading images: # " + images.numTotal + " (failed: " + images.numFailed + ")");
|
||||
|
||||
if (typeof options.complete === "function"){
|
||||
options.complete(images);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// TODO modify proxy to serve images with CORS enabled, where available
|
||||
function proxyGetImage(url, img, imageObj){
|
||||
var callback_name,
|
||||
scriptUrl = options.proxy,
|
||||
script;
|
||||
|
||||
link.href = url;
|
||||
url = link.href; // work around for pages with base href="" set - WARNING: this may change the url
|
||||
|
||||
callback_name = 'html2canvas_' + (count++);
|
||||
imageObj.callbackname = callback_name;
|
||||
|
||||
if (scriptUrl.indexOf("?") > -1) {
|
||||
scriptUrl += "&";
|
||||
} else {
|
||||
scriptUrl += "?";
|
||||
}
|
||||
scriptUrl += 'url=' + encodeURIComponent(url) + '&callback=' + callback_name;
|
||||
script = doc.createElement("script");
|
||||
|
||||
window[callback_name] = function(a){
|
||||
if (a.substring(0,6) === "error:"){
|
||||
imageObj.succeeded = false;
|
||||
images.numLoaded++;
|
||||
images.numFailed++;
|
||||
start();
|
||||
} else {
|
||||
setImageLoadHandlers(img, imageObj);
|
||||
img.src = a;
|
||||
}
|
||||
window[callback_name] = undefined; // to work with IE<9 // NOTE: that the undefined callback property-name still exists on the window object (for IE<9)
|
||||
try {
|
||||
delete window[callback_name]; // for all browser that support this
|
||||
} catch(ex) {}
|
||||
script.parentNode.removeChild(script);
|
||||
script = null;
|
||||
delete imageObj.script;
|
||||
delete imageObj.callbackname;
|
||||
};
|
||||
|
||||
script.setAttribute("type", "text/javascript");
|
||||
script.setAttribute("src", scriptUrl);
|
||||
imageObj.script = script;
|
||||
window.document.body.appendChild(script);
|
||||
|
||||
}
|
||||
|
||||
function loadPseudoElement(element, type) {
|
||||
var style = window.getComputedStyle(element, type),
|
||||
content = style.content;
|
||||
if (content.substr(0, 3) === 'url') {
|
||||
methods.loadImage(_html2canvas.Util.parseBackgroundImage(content)[0].args[0]);
|
||||
}
|
||||
loadBackgroundImages(style.backgroundImage, element);
|
||||
}
|
||||
|
||||
function loadPseudoElementImages(element) {
|
||||
loadPseudoElement(element, ":before");
|
||||
loadPseudoElement(element, ":after");
|
||||
}
|
||||
|
||||
function loadGradientImage(backgroundImage, bounds) {
|
||||
var img = _html2canvas.Generate.Gradient(backgroundImage, bounds);
|
||||
|
||||
if (img !== undefined){
|
||||
images[backgroundImage] = {
|
||||
img: img,
|
||||
succeeded: true
|
||||
};
|
||||
images.numTotal++;
|
||||
images.numLoaded++;
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
function invalidBackgrounds(background_image) {
|
||||
return (background_image && background_image.method && background_image.args && background_image.args.length > 0 );
|
||||
}
|
||||
|
||||
function loadBackgroundImages(background_image, el) {
|
||||
var bounds;
|
||||
|
||||
_html2canvas.Util.parseBackgroundImage(background_image).filter(invalidBackgrounds).forEach(function(background_image) {
|
||||
if (background_image.method === 'url') {
|
||||
methods.loadImage(background_image.args[0]);
|
||||
} else if(background_image.method.match(/\-?gradient$/)) {
|
||||
if(bounds === undefined) {
|
||||
bounds = _html2canvas.Util.Bounds(el);
|
||||
}
|
||||
loadGradientImage(background_image.value, bounds);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getImages (el) {
|
||||
var elNodeType = false;
|
||||
|
||||
// Firefox fails with permission denied on pages with iframes
|
||||
try {
|
||||
Util.Children(el).forEach(getImages);
|
||||
}
|
||||
catch( e ) {}
|
||||
|
||||
try {
|
||||
elNodeType = el.nodeType;
|
||||
} catch (ex) {
|
||||
elNodeType = false;
|
||||
Util.log("html2canvas: failed to access some element's nodeType - Exception: " + ex.message);
|
||||
}
|
||||
|
||||
if (elNodeType === 1 || elNodeType === undefined) {
|
||||
loadPseudoElementImages(el);
|
||||
try {
|
||||
loadBackgroundImages(Util.getCSS(el, 'backgroundImage'), el);
|
||||
} catch(e) {
|
||||
Util.log("html2canvas: failed to get background-image - Exception: " + e.message);
|
||||
}
|
||||
loadBackgroundImages(el);
|
||||
}
|
||||
}
|
||||
|
||||
function setImageLoadHandlers(img, imageObj) {
|
||||
img.onload = function() {
|
||||
if ( imageObj.timer !== undefined ) {
|
||||
// CORS succeeded
|
||||
window.clearTimeout( imageObj.timer );
|
||||
}
|
||||
|
||||
images.numLoaded++;
|
||||
imageObj.succeeded = true;
|
||||
img.onerror = img.onload = null;
|
||||
start();
|
||||
};
|
||||
img.onerror = function() {
|
||||
if (img.crossOrigin === "anonymous") {
|
||||
// CORS failed
|
||||
window.clearTimeout( imageObj.timer );
|
||||
|
||||
// let's try with proxy instead
|
||||
if ( options.proxy ) {
|
||||
var src = img.src;
|
||||
img = new Image();
|
||||
imageObj.img = img;
|
||||
img.src = src;
|
||||
|
||||
proxyGetImage( img.src, img, imageObj );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
images.numLoaded++;
|
||||
images.numFailed++;
|
||||
imageObj.succeeded = false;
|
||||
img.onerror = img.onload = null;
|
||||
start();
|
||||
};
|
||||
}
|
||||
|
||||
methods = {
|
||||
loadImage: function( src ) {
|
||||
var img, imageObj;
|
||||
if ( src && images[src] === undefined ) {
|
||||
img = new Image();
|
||||
if ( src.match(/data:image\/.*;base64,/i) ) {
|
||||
img.src = src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, '');
|
||||
imageObj = images[src] = {
|
||||
img: img
|
||||
};
|
||||
images.numTotal++;
|
||||
setImageLoadHandlers(img, imageObj);
|
||||
} else if ( isSameOrigin( src ) || options.allowTaint === true ) {
|
||||
imageObj = images[src] = {
|
||||
img: img
|
||||
};
|
||||
images.numTotal++;
|
||||
setImageLoadHandlers(img, imageObj);
|
||||
img.src = src;
|
||||
} else if ( supportCORS && !options.allowTaint && options.useCORS ) {
|
||||
// attempt to load with CORS
|
||||
|
||||
img.crossOrigin = "anonymous";
|
||||
imageObj = images[src] = {
|
||||
img: img
|
||||
};
|
||||
images.numTotal++;
|
||||
setImageLoadHandlers(img, imageObj);
|
||||
img.src = src;
|
||||
} else if ( options.proxy ) {
|
||||
imageObj = images[src] = {
|
||||
img: img
|
||||
};
|
||||
images.numTotal++;
|
||||
proxyGetImage( src, img, imageObj );
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
cleanupDOM: function(cause) {
|
||||
var img, src;
|
||||
if (!images.cleanupDone) {
|
||||
if (cause && typeof cause === "string") {
|
||||
Util.log("html2canvas: Cleanup because: " + cause);
|
||||
} else {
|
||||
Util.log("html2canvas: Cleanup after timeout: " + options.timeout + " ms.");
|
||||
}
|
||||
|
||||
for (src in images) {
|
||||
if (images.hasOwnProperty(src)) {
|
||||
img = images[src];
|
||||
if (typeof img === "object" && img.callbackname && img.succeeded === undefined) {
|
||||
// cancel proxy image request
|
||||
window[img.callbackname] = undefined; // to work with IE<9 // NOTE: that the undefined callback property-name still exists on the window object (for IE<9)
|
||||
try {
|
||||
delete window[img.callbackname]; // for all browser that support this
|
||||
} catch(ex) {}
|
||||
if (img.script && img.script.parentNode) {
|
||||
img.script.setAttribute("src", "about:blank"); // try to cancel running request
|
||||
img.script.parentNode.removeChild(img.script);
|
||||
}
|
||||
images.numLoaded++;
|
||||
images.numFailed++;
|
||||
Util.log("html2canvas: Cleaned up failed img: '" + src + "' Steps: " + images.numLoaded + " / " + images.numTotal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cancel any pending requests
|
||||
if(window.stop !== undefined) {
|
||||
window.stop();
|
||||
} else if(document.execCommand !== undefined) {
|
||||
document.execCommand("Stop", false);
|
||||
}
|
||||
if (document.close !== undefined) {
|
||||
document.close();
|
||||
}
|
||||
images.cleanupDone = true;
|
||||
if (!(cause && typeof cause === "string")) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
renderingDone: function() {
|
||||
if (timeoutTimer) {
|
||||
window.clearTimeout(timeoutTimer);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (options.timeout > 0) {
|
||||
timeoutTimer = window.setTimeout(methods.cleanupDOM, options.timeout);
|
||||
}
|
||||
|
||||
Util.log('html2canvas: Preload starts: finding background-images');
|
||||
images.firstRun = true;
|
||||
|
||||
getImages(element);
|
||||
|
||||
Util.log('html2canvas: Preload: Finding images');
|
||||
// load <img> images
|
||||
for (i = 0; i < imgLen; i+=1){
|
||||
methods.loadImage( domImages[i].getAttribute( "src" ) );
|
||||
}
|
||||
|
||||
images.firstRun = false;
|
||||
Util.log('html2canvas: Preload: Done.');
|
||||
if (images.numTotal === images.numLoaded) {
|
||||
start();
|
||||
}
|
||||
|
||||
return methods;
|
||||
};
|
123
src/Queue.js
@ -1,123 +0,0 @@
|
||||
function h2cRenderContext(width, height) {
|
||||
var storage = [];
|
||||
return {
|
||||
storage: storage,
|
||||
width: width,
|
||||
height: height,
|
||||
clip: function() {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "clip",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
translate: function() {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "translate",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
fill: function() {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "fill",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
save: function() {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "save",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
restore: function() {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "restore",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
fillRect: function () {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "fillRect",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
createPattern: function() {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "createPattern",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
drawShape: function() {
|
||||
|
||||
var shape = [];
|
||||
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "drawShape",
|
||||
'arguments': shape
|
||||
});
|
||||
|
||||
return {
|
||||
moveTo: function() {
|
||||
shape.push({
|
||||
name: "moveTo",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
lineTo: function() {
|
||||
shape.push({
|
||||
name: "lineTo",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
arcTo: function() {
|
||||
shape.push({
|
||||
name: "arcTo",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
bezierCurveTo: function() {
|
||||
shape.push({
|
||||
name: "bezierCurveTo",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
quadraticCurveTo: function() {
|
||||
shape.push({
|
||||
name: "quadraticCurveTo",
|
||||
'arguments': arguments
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
},
|
||||
drawImage: function () {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "drawImage",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
fillText: function () {
|
||||
storage.push({
|
||||
type: "function",
|
||||
name: "fillText",
|
||||
'arguments': arguments
|
||||
});
|
||||
},
|
||||
setVariable: function (variable, value) {
|
||||
storage.push({
|
||||
type: "variable",
|
||||
name: variable,
|
||||
'arguments': value
|
||||
});
|
||||
return value;
|
||||
}
|
||||
};
|
||||
}
|
425
src/Renderer.js
@ -1,101 +1,348 @@
|
||||
_html2canvas.Renderer = function(parseQueue, options){
|
||||
|
||||
// http://www.w3.org/TR/CSS21/zindex.html
|
||||
function createRenderQueue(parseQueue) {
|
||||
var queue = [],
|
||||
rootContext;
|
||||
|
||||
rootContext = (function buildStackingContext(rootNode) {
|
||||
var rootContext = {};
|
||||
function insert(context, node, specialParent) {
|
||||
var zi = (node.zIndex.zindex === 'auto') ? 0 : Number(node.zIndex.zindex),
|
||||
contextForChildren = context, // the stacking context for children
|
||||
isPositioned = node.zIndex.isPositioned,
|
||||
isFloated = node.zIndex.isFloated,
|
||||
stub = {node: node},
|
||||
childrenDest = specialParent; // where children without z-index should be pushed into
|
||||
|
||||
if (node.zIndex.ownStacking) {
|
||||
// '!' comes before numbers in sorted array
|
||||
contextForChildren = stub.context = { '!': [{node:node, children: []}]};
|
||||
childrenDest = undefined;
|
||||
} else if (isPositioned || isFloated) {
|
||||
childrenDest = stub.children = [];
|
||||
html2canvas.prototype.Renderer = function(queue){
|
||||
|
||||
var _ = this;
|
||||
|
||||
this.log('Renderer initiated');
|
||||
|
||||
this.each(this.opts.renderOrder.split(" "),function(i,renderer){
|
||||
|
||||
switch(renderer){
|
||||
case "canvas":
|
||||
_.canvas = document.createElement('canvas');
|
||||
if (_.canvas.getContext){
|
||||
_.canvasRenderer(queue);
|
||||
_.log('Using canvas renderer');
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case "flash":
|
||||
/*
|
||||
var script = document.createElement('script');
|
||||
script.type = "text/javascript";
|
||||
script.src = _.opts.flashCanvasPath;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(script, s);
|
||||
|
||||
|
||||
if (typeof FlashCanvas != "undefined") {
|
||||
_.canvas = initCanvas(document.getElementById("testflash"));
|
||||
FlashCanvas.initElement(_.canvas);
|
||||
_.ctx = _.canvas.getContext("2d");
|
||||
// _.canvas = document.createElement('canvas');
|
||||
//
|
||||
_.log('Using Flashcanvas renderer');
|
||||
_.canvasRenderer(queue);
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
break;
|
||||
case "html":
|
||||
// TODO add renderer
|
||||
_.log("Using HTML renderer");
|
||||
return false;
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
// this.log('No renderer chosen, rendering quit');
|
||||
return this;
|
||||
|
||||
// this.canvasRenderer(queue);
|
||||
|
||||
/*
|
||||
if (!this.canvas.getContext){
|
||||
|
||||
|
||||
}*/
|
||||
// TODO include Flashcanvas
|
||||
/*
|
||||
var script = document.createElement('script');
|
||||
script.type = "text/javascript";
|
||||
script.src = this.opts.flashCanvasPath;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(script, s);
|
||||
|
||||
if (zi === 0 && specialParent) {
|
||||
specialParent.push(stub);
|
||||
} else {
|
||||
if (!context[zi]) { context[zi] = []; }
|
||||
context[zi].push(stub);
|
||||
}
|
||||
if (typeof FlashCanvas != "undefined") {
|
||||
|
||||
FlashCanvas.initElement(this.canvas);
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
} */
|
||||
|
||||
}
|
||||
|
||||
node.zIndex.children.forEach(function(childNode) {
|
||||
insert(contextForChildren, childNode, childrenDest);
|
||||
});
|
||||
}
|
||||
insert(rootContext, rootNode);
|
||||
return rootContext;
|
||||
})(parseQueue);
|
||||
|
||||
function sortZ(context) {
|
||||
Object.keys(context).sort().forEach(function(zi) {
|
||||
var nonPositioned = [],
|
||||
floated = [],
|
||||
positioned = [],
|
||||
list = [];
|
||||
html2canvas.prototype.throttler = function(queue){
|
||||
|
||||
|
||||
};
|
||||
|
||||
// positioned after static
|
||||
context[zi].forEach(function(v) {
|
||||
if (v.node.zIndex.isPositioned || v.node.zIndex.opacity < 1) {
|
||||
// http://www.w3.org/TR/css3-color/#transparency
|
||||
// non-positioned element with opactiy < 1 should be stacked as if it were a positioned element with ‘z-index: 0’ and ‘opacity: 1’.
|
||||
positioned.push(v);
|
||||
} else if (v.node.zIndex.isFloated) {
|
||||
floated.push(v);
|
||||
} else {
|
||||
nonPositioned.push(v);
|
||||
}
|
||||
});
|
||||
|
||||
(function walk(arr) {
|
||||
arr.forEach(function(v) {
|
||||
list.push(v);
|
||||
if (v.children) { walk(v.children); }
|
||||
});
|
||||
})(nonPositioned.concat(floated, positioned));
|
||||
|
||||
list.forEach(function(v) {
|
||||
if (v.context) {
|
||||
sortZ(v.context);
|
||||
} else {
|
||||
queue.push(v.node);
|
||||
}
|
||||
});
|
||||
});
|
||||
html2canvas.prototype.canvasRenderContext = function(storageContext,ctx){
|
||||
|
||||
// set common settings for canvas
|
||||
ctx.textBaseline = "bottom";
|
||||
var _ = this;
|
||||
|
||||
|
||||
if (storageContext.clip){
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
// console.log(storageContext);
|
||||
ctx.rect(storageContext.clip.left,storageContext.clip.top,storageContext.clip.width,storageContext.clip.height);
|
||||
ctx.clip();
|
||||
|
||||
}
|
||||
|
||||
if (storageContext.ctx.storage){
|
||||
_.each(storageContext.ctx.storage,function(a,renderItem){
|
||||
|
||||
sortZ(rootContext);
|
||||
|
||||
switch(renderItem.type){
|
||||
case "variable":
|
||||
ctx[renderItem.name] = renderItem.arguments;
|
||||
break;
|
||||
case "function":
|
||||
if (renderItem.name=="fillRect"){
|
||||
|
||||
ctx.fillRect(
|
||||
renderItem.arguments[0],
|
||||
renderItem.arguments[1],
|
||||
renderItem.arguments[2],
|
||||
renderItem.arguments[3]
|
||||
);
|
||||
}else if(renderItem.name=="fillText"){
|
||||
// console.log(renderItem.arguments[0]);
|
||||
ctx.fillText(renderItem.arguments[0],renderItem.arguments[1],renderItem.arguments[2]);
|
||||
|
||||
}else if(renderItem.name=="drawImage"){
|
||||
// console.log(renderItem);
|
||||
// console.log(renderItem.arguments[0].width);
|
||||
if (renderItem.arguments[8] > 0 && renderItem.arguments[7]){
|
||||
ctx.drawImage(
|
||||
renderItem.arguments[0],
|
||||
renderItem.arguments[1],
|
||||
renderItem.arguments[2],
|
||||
renderItem.arguments[3],
|
||||
renderItem.arguments[4],
|
||||
renderItem.arguments[5],
|
||||
renderItem.arguments[6],
|
||||
renderItem.arguments[7],
|
||||
renderItem.arguments[8]
|
||||
);
|
||||
}
|
||||
}else{
|
||||
_.log(renderItem);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
if (storageContext.clip){
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
html2canvas.prototype.canvasRenderContextChildren = function(storageContext,parentctx){
|
||||
var ctx = storageContext.canvas.getContext('2d');
|
||||
|
||||
storageContext.canvasPosition = storageContext.canvasPosition || {};
|
||||
this.canvasRenderContext(storageContext,ctx);
|
||||
|
||||
|
||||
for (var s = 0; s<this.queue.length;){
|
||||
if (storageContext.parentStack && this.queue[s].canvas === storageContext.parentStack.canvas){
|
||||
var substorageContext = this.queue.splice(s,1)[0];
|
||||
|
||||
if (substorageContext.ctx.storage[5] && substorageContext.ctx.storage[5].arguments[0]=="Highlights"){
|
||||
console.log('ssssssadasda');
|
||||
}
|
||||
|
||||
this.canvasRenderContextChildren(substorageContext,ctx);
|
||||
// this.canvasRenderContext(substorageContext,ctx);
|
||||
// this.canvasRenderStorage(this.queue,ctx);
|
||||
|
||||
|
||||
}else{
|
||||
s++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (storageContext.ctx.storage[5] && storageContext.ctx.storage[5].arguments[0]=="Highlights"){
|
||||
$('body').append(parentctx.canvas);
|
||||
}
|
||||
//var parentctx = this.canvas.getContext("2d");
|
||||
|
||||
if (storageContext.canvas.width>0 && storageContext.canvas.height > 0){
|
||||
parentctx.drawImage(storageContext.canvas,(storageContext.canvasPosition.x || 0),(storageContext.canvasPosition.y || 0));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
html2canvas.prototype.canvasRenderStorage = function(queue,parentctx){
|
||||
|
||||
|
||||
|
||||
|
||||
for (var i = 0; i<queue.length;){
|
||||
var storageContext = queue.splice(0,1)[0];
|
||||
|
||||
|
||||
|
||||
// storageContext.removeOverflow = storageContext.removeOverflow || {};
|
||||
/*
|
||||
if (storageContext.canvas){
|
||||
this.canvasRenderContextChildren(storageContext,parentctx);
|
||||
|
||||
var ctx = storageContext.canvas.getContext('2d');
|
||||
|
||||
storageContext.canvasPosition = storageContext.canvasPosition || {};
|
||||
this.canvasRenderContext(storageContext,ctx);
|
||||
|
||||
for (var s = 0; s<this.queue.length;){
|
||||
if (this.queue[s].canvas === storageContext.canvas){
|
||||
var substorageContext = this.queue.splice(s,1)[0];
|
||||
substorageContext.canvasPosition = storageContext.canvasPosition || {};
|
||||
|
||||
this.canvasRenderContext(substorageContext,ctx);
|
||||
// this.canvasRenderStorage(this.queue,ctx);
|
||||
|
||||
}else{
|
||||
s++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//var parentctx = this.canvas.getContext("2d");
|
||||
|
||||
if (storageContext.canvas.width>0 && storageContext.canvas.height > 0){
|
||||
parentctx.drawImage(storageContext.canvas,(storageContext.canvasPosition.x || 0),(storageContext.canvasPosition.y || 0));
|
||||
}
|
||||
ctx = parentctx;
|
||||
|
||||
}else{
|
||||
*/
|
||||
storageContext.canvasPosition = storageContext.canvasPosition || {};
|
||||
this.canvasRenderContext(storageContext,parentctx);
|
||||
// }
|
||||
|
||||
|
||||
/*
|
||||
if (storageContext.newCanvas){
|
||||
var ctx = _.canvas.getContext("2d");
|
||||
ctx.drawImage(canvas,(storageContext.removeOverflow.left || 0),(storageContext.removeOverflow.top || 0));
|
||||
_.ctx = ctx;
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
html2canvas.prototype.canvasRenderer = function(queue){
|
||||
var _ = this;
|
||||
this.sortZ(this.zStack);
|
||||
queue = this.queue;
|
||||
//console.log(queue);
|
||||
|
||||
//queue = this.sortQueue(queue);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
this.canvas.width = Math.max($(document).width(),this.opts.canvasWidth);
|
||||
this.canvas.height = Math.max($(document).height(),this.opts.canvasHeight);
|
||||
|
||||
this.ctx = this.canvas.getContext("2d");
|
||||
|
||||
this.canvasRenderStorage(queue,this.ctx);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* Sort elements based on z-index and position attributes
|
||||
*/
|
||||
|
||||
/*
|
||||
html2canvas.prototype.sortQueue = function(queue){
|
||||
if (!this.opts.reorderZ || !this.needReorder) return queue;
|
||||
|
||||
var longest = 0;
|
||||
this.each(queue,function(i,e){
|
||||
if (longest<e.zIndex.length){
|
||||
longest = e.zIndex.length;
|
||||
}
|
||||
});
|
||||
|
||||
var counter = 0;
|
||||
//console.log(((queue.length).toString().length)-(count.length).toString().length);
|
||||
this.each(queue,function(i,e){
|
||||
|
||||
var more = ((queue.length).toString().length)-((counter).toString().length);
|
||||
while(longest>e.zIndex.length){
|
||||
e.zIndex += "0";
|
||||
}
|
||||
e.zIndex = e.zIndex+counter;
|
||||
|
||||
while((longest+more+(counter).toString().length)>e.zIndex.length){
|
||||
e.zIndex += "0";
|
||||
}
|
||||
counter++;
|
||||
// console.log(e.zIndex);
|
||||
});
|
||||
|
||||
|
||||
|
||||
queue = queue.sort(function(a,b){
|
||||
|
||||
if (a.zIndex < b.zIndex) return -1;
|
||||
if (a.zIndex > b.zIndex) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
return queue;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
function getRenderer(rendererName) {
|
||||
var renderer;
|
||||
|
||||
if (typeof options.renderer === "string" && _html2canvas.Renderer[rendererName] !== undefined) {
|
||||
renderer = _html2canvas.Renderer[rendererName](options);
|
||||
} else if (typeof rendererName === "function") {
|
||||
renderer = rendererName(options);
|
||||
} else {
|
||||
throw new Error("Unknown renderer");
|
||||
html2canvas.prototype.setContextVariable = function(ctx,variable,value){
|
||||
if (!ctx.storage){
|
||||
ctx[variable] = value;
|
||||
}else{
|
||||
ctx.storage.push(
|
||||
{
|
||||
type: "variable",
|
||||
name:variable,
|
||||
arguments:value
|
||||
});
|
||||
}
|
||||
|
||||
if ( typeof renderer !== "function" ) {
|
||||
throw new Error("Invalid renderer defined");
|
||||
}
|
||||
return renderer;
|
||||
}
|
||||
|
||||
return getRenderer(options.renderer)(parseQueue, options, document, createRenderQueue(parseQueue.stack), _html2canvas);
|
||||
};
|
||||
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
_html2canvas.Util.Support = function (options, doc) {
|
||||
|
||||
function supportSVGRendering() {
|
||||
var img = new Image(),
|
||||
canvas = doc.createElement("canvas"),
|
||||
ctx = (canvas.getContext === undefined) ? false : canvas.getContext("2d");
|
||||
if (ctx === false) {
|
||||
return false;
|
||||
}
|
||||
canvas.width = canvas.height = 10;
|
||||
img.src = [
|
||||
"data:image/svg+xml,",
|
||||
"<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'>",
|
||||
"<foreignObject width='10' height='10'>",
|
||||
"<div xmlns='http://www.w3.org/1999/xhtml' style='width:10;height:10;'>",
|
||||
"sup",
|
||||
"</div>",
|
||||
"</foreignObject>",
|
||||
"</svg>"
|
||||
].join("");
|
||||
try {
|
||||
ctx.drawImage(img, 0, 0);
|
||||
canvas.toDataURL();
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
_html2canvas.Util.log('html2canvas: Parse: SVG powered rendering available');
|
||||
return true;
|
||||
}
|
||||
|
||||
// Test whether we can use ranges to measure bounding boxes
|
||||
// Opera doesn't provide valid bounds.height/bottom even though it supports the method.
|
||||
|
||||
function supportRangeBounds() {
|
||||
var r, testElement, rangeBounds, rangeHeight, support = false;
|
||||
|
||||
if (doc.createRange) {
|
||||
r = doc.createRange();
|
||||
if (r.getBoundingClientRect) {
|
||||
testElement = doc.createElement('boundtest');
|
||||
testElement.style.height = "123px";
|
||||
testElement.style.display = "block";
|
||||
doc.body.appendChild(testElement);
|
||||
|
||||
r.selectNode(testElement);
|
||||
rangeBounds = r.getBoundingClientRect();
|
||||
rangeHeight = rangeBounds.height;
|
||||
|
||||
if (rangeHeight === 123) {
|
||||
support = true;
|
||||
}
|
||||
doc.body.removeChild(testElement);
|
||||
}
|
||||
}
|
||||
|
||||
return support;
|
||||
}
|
||||
|
||||
return {
|
||||
rangeBounds: supportRangeBounds(),
|
||||
svgRendering: options.svgRendering && supportSVGRendering()
|
||||
};
|
||||
};
|
288
src/Text.js
Normal file
@ -0,0 +1,288 @@
|
||||
|
||||
html2canvas.prototype.newText = function(el,textNode,stack,form){
|
||||
var ctx = stack.ctx;
|
||||
var family = this.getCSS(el,"font-family");
|
||||
var size = this.getCSS(el,"font-size");
|
||||
var color = this.getCSS(el,"color");
|
||||
|
||||
|
||||
|
||||
var text_decoration = this.getCSS(el,"text-decoration");
|
||||
var text_align = this.getCSS(el,"text-align");
|
||||
|
||||
|
||||
var letter_spacing = this.getCSS(el,"letter-spacing");
|
||||
|
||||
// apply text-transform:ation to the text
|
||||
textNode.nodeValue = this.textTransform(textNode.nodeValue,this.getCSS(el,"text-transform"));
|
||||
var text = this.trim(textNode.nodeValue);
|
||||
|
||||
//text = $.trim(text);
|
||||
if (text.length>0){
|
||||
|
||||
|
||||
|
||||
if (text_decoration!="none"){
|
||||
var metrics = this.fontMetrics(family,size);
|
||||
|
||||
}
|
||||
|
||||
var renderList,
|
||||
renderWords = false;
|
||||
|
||||
|
||||
text_align = text_align.replace(["-webkit-auto"],["auto"])
|
||||
|
||||
|
||||
if (this.opts.letterRendering == false && /^(left|right|justify|auto)$/.test(text_align) && /^(normal|none)$/.test(letter_spacing)){
|
||||
// this.setContextVariable(ctx,"textAlign",text_align);
|
||||
renderWords = true;
|
||||
renderList = textNode.nodeValue.split(/(\b| )/);
|
||||
|
||||
}else{
|
||||
// this.setContextVariable(ctx,"textAlign","left");
|
||||
renderList = textNode.nodeValue.split("");
|
||||
}
|
||||
|
||||
this.setFont(ctx,el,false);
|
||||
|
||||
|
||||
/*
|
||||
if (stack.clip){
|
||||
ctx.rect (stack.clip.left, stack.clip.top, stack.clip.width, stack.clip.height);
|
||||
ctx.clip();
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
var oldTextNode = textNode;
|
||||
for(var c=0;c<renderList.length;c++){
|
||||
|
||||
|
||||
// IE 9 bug
|
||||
if (typeof oldTextNode.nodeValue != "string"){
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO only do the splitting for non-range prints
|
||||
var newTextNode = oldTextNode.splitText(renderList[c].length);
|
||||
|
||||
if (text_decoration!="none" || this.trim(oldTextNode.nodeValue).length != 0){
|
||||
|
||||
|
||||
|
||||
|
||||
if (this.support.rangeBounds){
|
||||
// getBoundingClientRect is supported for ranges
|
||||
if (document.createRange){
|
||||
var range = document.createRange();
|
||||
range.selectNode(oldTextNode);
|
||||
}else{
|
||||
// TODO add IE support
|
||||
var range = document.body.createTextRange();
|
||||
}
|
||||
if (range.getBoundingClientRect()){
|
||||
var bounds = range.getBoundingClientRect();
|
||||
}else{
|
||||
var bounds = {};
|
||||
}
|
||||
}else{
|
||||
// it isn't supported, so let's wrap it inside an element instead and the bounds there
|
||||
|
||||
var parent = oldTextNode.parentNode;
|
||||
var wrapElement = document.createElement('wrapper');
|
||||
var backupText = oldTextNode.cloneNode(true);
|
||||
wrapElement.appendChild(oldTextNode.cloneNode(true));
|
||||
parent.replaceChild(wrapElement,oldTextNode);
|
||||
|
||||
var bounds = this.getBounds(wrapElement);
|
||||
|
||||
parent.replaceChild(backupText,wrapElement);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// console.log(range);
|
||||
// console.log("'"+oldTextNode.nodeValue+"'"+bounds.left)
|
||||
this.printText(oldTextNode.nodeValue,bounds.left,bounds.bottom,ctx);
|
||||
|
||||
switch(text_decoration) {
|
||||
case "underline":
|
||||
// Draws a line at the baseline of the font
|
||||
// TODO As some browsers display the line as more than 1px if the font-size is big, need to take that into account both in position and size
|
||||
this.newRect(ctx,bounds.left,Math.round(bounds.top+metrics.baseline+metrics.lineWidth),bounds.width,1,color);
|
||||
break;
|
||||
case "overline":
|
||||
this.newRect(ctx,bounds.left,bounds.top,bounds.width,1,color);
|
||||
break;
|
||||
case "line-through":
|
||||
// TODO try and find exact position for line-through
|
||||
this.newRect(ctx,bounds.left,Math.ceil(bounds.top+metrics.middle+metrics.lineWidth),bounds.width,1,color);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
oldTextNode = newTextNode;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.setFont = function(ctx,el,align){
|
||||
|
||||
var family = this.getCSS(el,"font-family");
|
||||
var size = this.getCSS(el,"font-size");
|
||||
var color = this.getCSS(el,"color");
|
||||
|
||||
var bold = this.getCSS(el,"font-weight");
|
||||
var font_style = this.getCSS(el,"font-style");
|
||||
var font_variant = this.getCSS(el,"font-variant");
|
||||
|
||||
switch(bold){
|
||||
case 401:
|
||||
bold = "bold";
|
||||
break;
|
||||
case 400:
|
||||
bold = "normal";
|
||||
break;
|
||||
}
|
||||
|
||||
var font = font_variant+" "+bold+" "+font_style+" "+size+" "+family;
|
||||
|
||||
|
||||
this.setContextVariable(ctx,"fillStyle",color);
|
||||
this.setContextVariable(ctx,"font",font);
|
||||
if (align){
|
||||
this.setContextVariable(ctx,"textAlign","right");
|
||||
}else{
|
||||
this.setContextVariable(ctx,"textAlign","left");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function to find baseline for font with a specicic size
|
||||
*/
|
||||
html2canvas.prototype.fontMetrics = function(font,fontSize){
|
||||
|
||||
|
||||
var findMetrics = this.fontData.indexOf(font+"-"+fontSize);
|
||||
|
||||
if (findMetrics>-1){
|
||||
return this.fontData[findMetrics+1];
|
||||
}
|
||||
|
||||
var container = document.createElement('div');
|
||||
document.getElementsByTagName('body')[0].appendChild(container);
|
||||
|
||||
// jquery to speed this up, TODO remove jquery dependancy
|
||||
$(container).css({
|
||||
visibility:'hidden',
|
||||
fontFamily:font,
|
||||
fontSize:fontSize,
|
||||
margin:0,
|
||||
padding:0
|
||||
});
|
||||
|
||||
|
||||
|
||||
var img = document.createElement('img');
|
||||
|
||||
// TODO add another image
|
||||
img.src = "http://html2canvas.hertzen.com/images/8.jpg";
|
||||
img.width = 1;
|
||||
img.height = 1;
|
||||
|
||||
$(img).css({
|
||||
margin:0,
|
||||
padding:0
|
||||
});
|
||||
var span = document.createElement('span');
|
||||
|
||||
$(span).css({
|
||||
fontFamily:font,
|
||||
fontSize:fontSize,
|
||||
margin:0,
|
||||
padding:0
|
||||
});
|
||||
|
||||
|
||||
span.appendChild(document.createTextNode('Hidden Text'));
|
||||
container.appendChild(span);
|
||||
container.appendChild(img);
|
||||
var baseline = (img.offsetTop-span.offsetTop)+1;
|
||||
|
||||
container.removeChild(span);
|
||||
container.appendChild(document.createTextNode('Hidden Text'));
|
||||
|
||||
$(container).css('line-height','normal');
|
||||
$(img).css("vertical-align","super");
|
||||
var middle = (img.offsetTop-container.offsetTop)+1;
|
||||
|
||||
var metricsObj = {
|
||||
baseline: baseline,
|
||||
lineWidth: 1,
|
||||
middle: middle
|
||||
};
|
||||
|
||||
|
||||
this.fontData.push(font+"-"+fontSize);
|
||||
this.fontData.push(metricsObj);
|
||||
|
||||
$(container).remove();
|
||||
|
||||
|
||||
|
||||
return metricsObj;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Function to apply text-transform attribute to text
|
||||
*/
|
||||
html2canvas.prototype.textTransform = function(text,transform){
|
||||
switch(transform){
|
||||
case "lowercase":
|
||||
return text.toLowerCase();
|
||||
break;
|
||||
|
||||
case "capitalize":
|
||||
return text.replace( /(^|\s|:|-|\(|\))([a-z])/g , function(m,p1,p2){
|
||||
return p1+p2.toUpperCase();
|
||||
} );
|
||||
break;
|
||||
|
||||
case "uppercase":
|
||||
return text.toUpperCase();
|
||||
break;
|
||||
default:
|
||||
return text;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*Function to trim whitespace from text
|
||||
*/
|
||||
html2canvas.prototype.trim = function(text) {
|
||||
return text.replace(/^\s*/, "").replace(/\s*$/, "");
|
||||
}
|
46
src/Traversing.js
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
|
||||
html2canvas.prototype.parseElement = function(element,stack){
|
||||
var _ = this;
|
||||
this.each(element.children,function(index,el){
|
||||
_.parsing(el,stack);
|
||||
});
|
||||
|
||||
this.log('Render queue stored');
|
||||
this.opts.storageReady(this);
|
||||
this.finish();
|
||||
}
|
||||
|
||||
|
||||
|
||||
html2canvas.prototype.parsing = function(el,stack){
|
||||
|
||||
if (this.getCSS(el,'display') != "none" && this.getCSS(el,'visibility')!="hidden"){
|
||||
|
||||
var _ = this;
|
||||
|
||||
stack = this.newElement(el,stack) || stack;
|
||||
|
||||
var ctx = stack.ctx;
|
||||
|
||||
if (!this.ignoreRe.test(el.nodeName)){
|
||||
// TODO remove jQuery dependancy
|
||||
this.each(this.contentsInZ(el),function(cid,node){
|
||||
|
||||
if (node.nodeType==1){
|
||||
// element
|
||||
_.parsing(node,stack);
|
||||
}else if (node.nodeType==3){
|
||||
_.newText(el,node,stack);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
340
src/Util.js
@ -1,81 +1,285 @@
|
||||
window.html2canvas = function(elements, opts) {
|
||||
elements = (elements.length) ? elements : [elements];
|
||||
var queue,
|
||||
canvas,
|
||||
options = {
|
||||
// general
|
||||
logging: false,
|
||||
elements: elements,
|
||||
background: "#fff",
|
||||
|
||||
// preload options
|
||||
proxy: null,
|
||||
timeout: 0, // no timeout
|
||||
useCORS: false, // try to load images as CORS (where available), before falling back to proxy
|
||||
allowTaint: false, // whether to allow images to taint the canvas, won't need proxy if set to true
|
||||
// Simple logger
|
||||
html2canvas.prototype.log = function(a){
|
||||
if (this.opts.logging){
|
||||
|
||||
this.opts.logger(a);
|
||||
|
||||
// parse options
|
||||
svgRendering: false, // use svg powered rendering where available (FF11+)
|
||||
ignoreElements: "IFRAME|OBJECT|PARAM",
|
||||
useOverflow: true,
|
||||
letterRendering: false,
|
||||
chinese: false,
|
||||
|
||||
// render options
|
||||
|
||||
width: null,
|
||||
height: null,
|
||||
taintTest: true, // do a taint test with all images before applying to canvas
|
||||
renderer: "Canvas"
|
||||
};
|
||||
|
||||
options = _html2canvas.Util.Extend(opts, options);
|
||||
|
||||
_html2canvas.logging = options.logging;
|
||||
options.complete = function( images ) {
|
||||
|
||||
if (typeof options.onpreloaded === "function") {
|
||||
if ( options.onpreloaded( images ) === false ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
queue = _html2canvas.Parse( images, options );
|
||||
}
|
||||
|
||||
if (typeof options.onparsed === "function") {
|
||||
if ( options.onparsed( queue ) === false ) {
|
||||
return;
|
||||
}
|
||||
html2canvas.prototype.withinBounds = function(src,dst){
|
||||
if (!src) return true;
|
||||
// return true;
|
||||
return (
|
||||
(src.left <= dst.left || dst.left+dst.width < src.left) &&
|
||||
(src.top <= dst.top || dst.top+dst.height < src.top)
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
html2canvas.prototype.clipBounds = function(src,dst){
|
||||
|
||||
var x = Math.max(src.left,dst.left);
|
||||
var y = Math.max(src.top,dst.top);
|
||||
|
||||
var x2 = Math.min((src.left+src.width),(dst.left+dst.width));
|
||||
var y2 = Math.min((src.top+src.height),(dst.top+dst.height));
|
||||
|
||||
return {
|
||||
left:x,
|
||||
top:y,
|
||||
width:x2-x,
|
||||
height:y2-y
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function to provide bounds for element
|
||||
* @return {Bounds} object with position and dimension information
|
||||
*/
|
||||
html2canvas.prototype.getBounds = function(el){
|
||||
|
||||
window.scroll(0,0);
|
||||
|
||||
if (el.getBoundingClientRect){
|
||||
var clientRect = el.getBoundingClientRect();
|
||||
var bounds = {};
|
||||
// need to create new object, as clientrect bounds can't be modified, thanks pufuwozu
|
||||
// TODO add scroll position to bounds, so no scrolling of window necessary
|
||||
bounds.top = clientRect.top;
|
||||
bounds.bottom = clientRect.bottom || (clientRect.top + clientRect.height);
|
||||
bounds.left = clientRect.left;
|
||||
bounds.width = clientRect.width;
|
||||
bounds.height = clientRect.height;
|
||||
|
||||
|
||||
|
||||
return bounds;
|
||||
}else{
|
||||
|
||||
// TODO remove jQuery dependancy
|
||||
var p = $(el).offset();
|
||||
|
||||
return {
|
||||
left: p.left + this.getCSS(el,"border-left-width",true),
|
||||
top: p.top + this.getCSS(el,"border-top-width",true),
|
||||
width:$(el).innerWidth(),
|
||||
height:$(el).innerHeight()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Function for looping through array
|
||||
*/
|
||||
html2canvas.prototype.each = function(arrayLoop,callbackFunc){
|
||||
callbackFunc = callbackFunc || function(){};
|
||||
for (var i=0;i<arrayLoop.length;i++){
|
||||
if (callbackFunc(i,arrayLoop[i]) === false) return;
|
||||
}
|
||||
}
|
||||
|
||||
canvas = _html2canvas.Renderer( queue, options );
|
||||
|
||||
if (typeof options.onrendered === "function") {
|
||||
options.onrendered( canvas );
|
||||
/*
|
||||
* Function to get childNodes of an element in the order they should be rendered (based on z-index)
|
||||
* reference http://www.w3.org/TR/CSS21/zindex.html
|
||||
*/
|
||||
|
||||
html2canvas.prototype.contentsInZ = function(el){
|
||||
|
||||
// TODO remove jQuery dependency
|
||||
|
||||
var contents = $(el).contents();
|
||||
|
||||
return contents;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function for fetching the element attribute
|
||||
*/
|
||||
html2canvas.prototype.getAttr = function(el,attribute){
|
||||
return el.getAttribute(attribute);
|
||||
//return $(el).attr(attribute);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to extend object
|
||||
*/
|
||||
html2canvas.prototype.extendObj = function(options,defaults){
|
||||
for (var key in options){
|
||||
defaults[key] = options[key];
|
||||
}
|
||||
return defaults;
|
||||
}
|
||||
|
||||
/*
|
||||
*todo remove this function
|
||||
html2canvas.prototype.leadingZero = function(num,size){
|
||||
|
||||
var s = "000000000" + num;
|
||||
return s.substr(s.length-size);
|
||||
}
|
||||
*/
|
||||
|
||||
html2canvas.prototype.zContext = function(zindex){
|
||||
return {
|
||||
zindex: zindex,
|
||||
children: []
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.setZ = function(zindex,position,parentZ,parentNode){
|
||||
// TODO fix static elements overlapping relative/absolute elements under same stack, if they are defined after them
|
||||
if (!parentZ){
|
||||
this.zStack = new this.zContext(0);
|
||||
return this.zStack;
|
||||
}
|
||||
|
||||
if (zindex!="auto"){
|
||||
this.needReorder = true;
|
||||
var newContext = new this.zContext(zindex);
|
||||
parentZ.children.push(newContext);
|
||||
|
||||
return newContext;
|
||||
|
||||
}else {
|
||||
return parentZ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
html2canvas.prototype.sortZ = function(zStack){
|
||||
var subStacks = [];
|
||||
var stackValues = [];
|
||||
var _ = this;
|
||||
|
||||
this.each(zStack.children, function(i,stackChild){
|
||||
if (stackChild.children && stackChild.children.length > 0){
|
||||
subStacks.push(stackChild);
|
||||
stackValues.push(stackChild.zindex);
|
||||
}else{
|
||||
|
||||
|
||||
_.queue.push(stackChild);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
stackValues.sort(function(a,b){
|
||||
return a - b
|
||||
});
|
||||
|
||||
this.each(stackValues, function(i,zValue){
|
||||
for (var s = 0;s<=subStacks.length;s++){
|
||||
if (subStacks[s].zindex == zValue){
|
||||
var stackChild = subStacks.splice(s,1);
|
||||
_.sortZ(stackChild[0]);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
*todo remove this function
|
||||
|
||||
html2canvas.prototype.formatZ = function(zindex,position,parentZ,parentNode){
|
||||
|
||||
if (!parentZ){
|
||||
parentZ = "0";
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
if (position!="static" && parentZ.charAt(0)=="0"){
|
||||
this.needReorder = true;
|
||||
parentZ = "1"+parentZ.slice(1);
|
||||
}
|
||||
|
||||
// for pages without images, we still want this to be async, i.e. return methods before executing
|
||||
window.setTimeout( function(){
|
||||
_html2canvas.Preload( options );
|
||||
}, 0 );
|
||||
if (zindex=="auto"){
|
||||
var parentPosition = this.getCSS(parentNode,"position");
|
||||
if (parentPosition!="static" && typeof parentPosition != "undefined"){
|
||||
zindex = 0;
|
||||
}
|
||||
else{
|
||||
return parentZ;
|
||||
}
|
||||
}
|
||||
|
||||
var b = this.leadingZero(this.numDraws,9);
|
||||
|
||||
|
||||
var s = this.leadingZero(zindex+1,9);
|
||||
|
||||
return {
|
||||
render: function( queue, opts ) {
|
||||
return _html2canvas.Renderer( queue, _html2canvas.Util.Extend(opts, options) );
|
||||
},
|
||||
parse: function( images, opts ) {
|
||||
return _html2canvas.Parse( images, _html2canvas.Util.Extend(opts, options) );
|
||||
},
|
||||
preload: function( opts ) {
|
||||
return _html2canvas.Preload( _html2canvas.Util.Extend(opts, options) );
|
||||
},
|
||||
log: _html2canvas.Util.log
|
||||
};
|
||||
};
|
||||
// var s = "000000000" + num;
|
||||
return parentZ+""+""+s+""+b;
|
||||
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Get element childNodes
|
||||
*/
|
||||
|
||||
html2canvas.prototype.getContents = function(el){
|
||||
return (el.nodeName == "iframe" ) ?
|
||||
el.contentDocument || el.contentWindow.document :
|
||||
el.childNodes;
|
||||
}
|
||||
|
||||
window.html2canvas.log = _html2canvas.Util.log; // for renderers
|
||||
window.html2canvas.Renderer = {
|
||||
Canvas: undefined // We are assuming this will be used
|
||||
};
|
||||
|
||||
/*
|
||||
* Function for fetching the css attribute
|
||||
* TODO remove jQuery dependancy
|
||||
*/
|
||||
html2canvas.prototype.getCSS = function(el,attribute,intOnly){
|
||||
if (intOnly){
|
||||
return parseInt($(el).css(attribute),10);
|
||||
}else{
|
||||
return $(el).css(attribute);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
html2canvas.prototype.getIndex = function(array,src){
|
||||
|
||||
if (array.indexOf){
|
||||
return array.indexOf(src);
|
||||
}else{
|
||||
for(var i = 0; i < array.length; i++){
|
||||
if(this[i] == src) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
html2canvas.prototype.isSameOrigin = function(url){
|
||||
var link = document.createElement("a");
|
||||
link.href = url;
|
||||
|
||||
return ((link.protocol + link.host) == this.pageOrigin);
|
||||
}
|
||||
|
88
src/plugins/jquery.plugin.html2canvas.js
Normal file
@ -0,0 +1,88 @@
|
||||
|
||||
/*
|
||||
* jQuery helper plugin for examples and tests
|
||||
*/
|
||||
|
||||
(function( $ ){
|
||||
$.fn.html2canvas = function(options) {
|
||||
|
||||
var date = new Date();
|
||||
var message,
|
||||
timeoutTimer,
|
||||
timer = date.getTime();
|
||||
|
||||
var object = $.extend({},{
|
||||
logging: false,
|
||||
proxyUrl: "http://html2canvas.appspot.com/", // running html2canvas-python proxy
|
||||
ready: function(renderer) {
|
||||
|
||||
var finishTime = new Date();
|
||||
// console.log((finishTime.getTime()-timer)/1000);
|
||||
|
||||
|
||||
document.body.appendChild(renderer.canvas);
|
||||
|
||||
|
||||
|
||||
var canvas = $(renderer.canvas);
|
||||
canvas.css('position','absolute')
|
||||
.css('left',0).css('top',0);
|
||||
|
||||
|
||||
|
||||
// $('body').append(canvas);
|
||||
$(canvas).siblings().toggle();
|
||||
|
||||
throwMessage('Screenshot created in '+ ((finishTime.getTime()-timer)/1000) + " seconds<br />Total of "+renderer.numDraws+" draws performed",4000);
|
||||
|
||||
|
||||
$(window).click(function(){
|
||||
if (!canvas.is(':visible')){
|
||||
$(canvas).toggle().siblings().toggle();
|
||||
throwMessage("Canvas Render visible");
|
||||
} else{
|
||||
$(canvas).siblings().toggle();
|
||||
$(canvas).toggle();
|
||||
throwMessage("Canvas Render hidden");
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
},options)
|
||||
|
||||
new html2canvas(this.get(0), object);
|
||||
|
||||
|
||||
function throwMessage(msg,duration){
|
||||
|
||||
window.clearTimeout(timeoutTimer);
|
||||
timeoutTimer = window.setTimeout(function(){
|
||||
message.fadeOut(function(){
|
||||
message.remove();
|
||||
});
|
||||
},duration || 2000);
|
||||
$(message).remove();
|
||||
message = $('<div />').html(msg).css({
|
||||
margin:0,
|
||||
padding:10,
|
||||
background: "#000",
|
||||
opacity:0.7,
|
||||
position:"fixed",
|
||||
top:10,
|
||||
right:10,
|
||||
fontFamily: 'Tahoma' ,
|
||||
color:'#fff',
|
||||
fontSize:12,
|
||||
borderRadius:12,
|
||||
width:'auto',
|
||||
height:'auto',
|
||||
textAlign:'center',
|
||||
textDecoration:'none'
|
||||
}).hide().fadeIn().appendTo('body');
|
||||
}
|
||||
|
||||
};
|
||||
})( jQuery );
|
||||
|
@ -1,128 +0,0 @@
|
||||
_html2canvas.Renderer.Canvas = function(options) {
|
||||
options = options || {};
|
||||
|
||||
var doc = document,
|
||||
safeImages = [],
|
||||
testCanvas = document.createElement("canvas"),
|
||||
testctx = testCanvas.getContext("2d"),
|
||||
Util = _html2canvas.Util,
|
||||
canvas = options.canvas || doc.createElement('canvas');
|
||||
|
||||
function createShape(ctx, args) {
|
||||
ctx.beginPath();
|
||||
args.forEach(function(arg) {
|
||||
ctx[arg.name].apply(ctx, arg['arguments']);
|
||||
});
|
||||
ctx.closePath();
|
||||
}
|
||||
|
||||
function safeImage(item) {
|
||||
if (safeImages.indexOf(item['arguments'][0].src ) === -1) {
|
||||
testctx.drawImage(item['arguments'][0], 0, 0);
|
||||
try {
|
||||
testctx.getImageData(0, 0, 1, 1);
|
||||
} catch(e) {
|
||||
testCanvas = doc.createElement("canvas");
|
||||
testctx = testCanvas.getContext("2d");
|
||||
return false;
|
||||
}
|
||||
safeImages.push(item['arguments'][0].src);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function renderItem(ctx, item) {
|
||||
switch(item.type){
|
||||
case "variable":
|
||||
ctx[item.name] = item['arguments'];
|
||||
break;
|
||||
case "function":
|
||||
switch(item.name) {
|
||||
case "createPattern":
|
||||
if (item['arguments'][0].width > 0 && item['arguments'][0].height > 0) {
|
||||
try {
|
||||
ctx.fillStyle = ctx.createPattern(item['arguments'][0], "repeat");
|
||||
}
|
||||
catch(e) {
|
||||
Util.log("html2canvas: Renderer: Error creating pattern", e.message);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "drawShape":
|
||||
createShape(ctx, item['arguments']);
|
||||
break;
|
||||
case "drawImage":
|
||||
if (item['arguments'][8] > 0 && item['arguments'][7] > 0) {
|
||||
if (!options.taintTest || (options.taintTest && safeImage(item))) {
|
||||
ctx.drawImage.apply( ctx, item['arguments'] );
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ctx[item.name].apply(ctx, item['arguments']);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return function(parsedData, options, document, queue, _html2canvas) {
|
||||
var ctx = canvas.getContext("2d"),
|
||||
newCanvas,
|
||||
bounds,
|
||||
fstyle,
|
||||
zStack = parsedData.stack;
|
||||
|
||||
canvas.width = canvas.style.width = options.width || zStack.ctx.width;
|
||||
canvas.height = canvas.style.height = options.height || zStack.ctx.height;
|
||||
|
||||
fstyle = ctx.fillStyle;
|
||||
ctx.fillStyle = (Util.isTransparent(zStack.backgroundColor) && options.background !== undefined) ? options.background : parsedData.backgroundColor;
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.fillStyle = fstyle;
|
||||
|
||||
queue.forEach(function(storageContext) {
|
||||
// set common settings for canvas
|
||||
ctx.textBaseline = "bottom";
|
||||
ctx.save();
|
||||
|
||||
if (storageContext.transform.matrix) {
|
||||
ctx.translate(storageContext.transform.origin[0], storageContext.transform.origin[1]);
|
||||
ctx.transform.apply(ctx, storageContext.transform.matrix);
|
||||
ctx.translate(-storageContext.transform.origin[0], -storageContext.transform.origin[1]);
|
||||
}
|
||||
|
||||
if (storageContext.clip){
|
||||
ctx.beginPath();
|
||||
ctx.rect(storageContext.clip.left, storageContext.clip.top, storageContext.clip.width, storageContext.clip.height);
|
||||
ctx.clip();
|
||||
}
|
||||
|
||||
if (storageContext.ctx.storage) {
|
||||
storageContext.ctx.storage.forEach(function(item) {
|
||||
renderItem(ctx, item);
|
||||
});
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
});
|
||||
|
||||
Util.log("html2canvas: Renderer: Canvas renderer done - returning canvas obj");
|
||||
|
||||
if (options.elements.length === 1) {
|
||||
if (typeof options.elements[0] === "object" && options.elements[0].nodeName !== "BODY") {
|
||||
// crop image to the bounds of selected (single) element
|
||||
bounds = _html2canvas.Util.Bounds(options.elements[0]);
|
||||
newCanvas = document.createElement('canvas');
|
||||
newCanvas.width = Math.ceil(bounds.width);
|
||||
newCanvas.height = Math.ceil(bounds.height);
|
||||
ctx = newCanvas.getContext("2d");
|
||||
|
||||
ctx.drawImage(canvas, bounds.left, bounds.top, bounds.width, bounds.height, 0, 0, bounds.width, bounds.height);
|
||||
canvas = null;
|
||||
return newCanvas;
|
||||
}
|
||||
}
|
||||
|
||||
return canvas;
|
||||
};
|
||||
};
|
@ -1,206 +0,0 @@
|
||||
/*
|
||||
html2canvas @VERSION@ <http://html2canvas.hertzen.com>
|
||||
Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
|
||||
http://www.twitter.com/niklasvh
|
||||
|
||||
Released under MIT License
|
||||
*/
|
||||
|
||||
|
||||
// WARNING THIS file is outdated, and hasn't been tested in quite a while
|
||||
|
||||
_html2canvas.Renderer.SVG = function( options ) {
|
||||
|
||||
options = options || {};
|
||||
|
||||
var doc = document,
|
||||
svgNS = "http://www.w3.org/2000/svg",
|
||||
svg = doc.createElementNS(svgNS, "svg"),
|
||||
xlinkNS = "http://www.w3.org/1999/xlink",
|
||||
defs = doc.createElementNS(svgNS, "defs"),
|
||||
i,
|
||||
a,
|
||||
queueLen,
|
||||
storageLen,
|
||||
storageContext,
|
||||
renderItem,
|
||||
el,
|
||||
settings = {},
|
||||
text,
|
||||
fontStyle,
|
||||
clipId = 0,
|
||||
methods;
|
||||
|
||||
|
||||
methods = {
|
||||
_create: function( zStack, options, doc, queue, _html2canvas ) {
|
||||
svg.setAttribute("version", "1.1");
|
||||
svg.setAttribute("baseProfile", "full");
|
||||
|
||||
svg.setAttribute("viewBox", "0 0 " + Math.max(zStack.ctx.width, options.width) + " " + Math.max(zStack.ctx.height, options.height));
|
||||
svg.setAttribute("width", Math.max(zStack.ctx.width, options.width) + "px");
|
||||
svg.setAttribute("height", Math.max(zStack.ctx.height, options.height) + "px");
|
||||
svg.setAttribute("preserveAspectRatio", "none");
|
||||
svg.appendChild(defs);
|
||||
|
||||
|
||||
|
||||
for (i = 0, queueLen = queue.length; i < queueLen; i+=1){
|
||||
|
||||
storageContext = queue.splice(0, 1)[0];
|
||||
storageContext.canvasPosition = storageContext.canvasPosition || {};
|
||||
|
||||
//this.canvasRenderContext(storageContext,parentctx);
|
||||
|
||||
|
||||
/*
|
||||
if (storageContext.clip){
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
// console.log(storageContext);
|
||||
ctx.rect(storageContext.clip.left, storageContext.clip.top, storageContext.clip.width, storageContext.clip.height);
|
||||
ctx.clip();
|
||||
|
||||
}*/
|
||||
|
||||
if (storageContext.ctx.storage){
|
||||
|
||||
for (a = 0, storageLen = storageContext.ctx.storage.length; a < storageLen; a+=1){
|
||||
|
||||
renderItem = storageContext.ctx.storage[a];
|
||||
|
||||
|
||||
|
||||
switch(renderItem.type){
|
||||
case "variable":
|
||||
settings[renderItem.name] = renderItem['arguments'];
|
||||
break;
|
||||
case "function":
|
||||
if (renderItem.name === "fillRect") {
|
||||
|
||||
el = doc.createElementNS(svgNS, "rect");
|
||||
el.setAttribute("x", renderItem['arguments'][0]);
|
||||
el.setAttribute("y", renderItem['arguments'][1]);
|
||||
el.setAttribute("width", renderItem['arguments'][2]);
|
||||
el.setAttribute("height", renderItem['arguments'][3]);
|
||||
el.setAttribute("fill", settings.fillStyle);
|
||||
svg.appendChild(el);
|
||||
|
||||
} else if(renderItem.name === "fillText") {
|
||||
el = doc.createElementNS(svgNS, "text");
|
||||
|
||||
fontStyle = settings.font.split(" ");
|
||||
|
||||
el.style.fontVariant = fontStyle.splice(0, 1)[0];
|
||||
el.style.fontWeight = fontStyle.splice(0, 1)[0];
|
||||
el.style.fontStyle = fontStyle.splice(0, 1)[0];
|
||||
el.style.fontSize = fontStyle.splice(0, 1)[0];
|
||||
|
||||
el.setAttribute("x", renderItem['arguments'][1]);
|
||||
el.setAttribute("y", renderItem['arguments'][2] - (parseInt(el.style.fontSize, 10) + 3));
|
||||
|
||||
el.setAttribute("fill", settings.fillStyle);
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO get proper baseline
|
||||
el.style.dominantBaseline = "text-before-edge";
|
||||
el.style.fontFamily = fontStyle.join(" ");
|
||||
|
||||
text = doc.createTextNode(renderItem['arguments'][0]);
|
||||
el.appendChild(text);
|
||||
|
||||
|
||||
svg.appendChild(el);
|
||||
|
||||
|
||||
|
||||
} else if(renderItem.name === "drawImage") {
|
||||
|
||||
if (renderItem['arguments'][8] > 0 && renderItem['arguments'][7]){
|
||||
|
||||
// TODO check whether even any clipping is necessary for this particular image
|
||||
el = doc.createElementNS(svgNS, "clipPath");
|
||||
el.setAttribute("id", "clipId" + clipId);
|
||||
|
||||
text = doc.createElementNS(svgNS, "rect");
|
||||
text.setAttribute("x", renderItem['arguments'][5] );
|
||||
text.setAttribute("y", renderItem['arguments'][6]);
|
||||
|
||||
text.setAttribute("width", renderItem['arguments'][3]);
|
||||
text.setAttribute("height", renderItem['arguments'][4]);
|
||||
el.appendChild(text);
|
||||
defs.appendChild(el);
|
||||
|
||||
el = doc.createElementNS(svgNS, "image");
|
||||
el.setAttributeNS(xlinkNS, "xlink:href", renderItem['arguments'][0].src);
|
||||
el.setAttribute("width", renderItem['arguments'][7]);
|
||||
el.setAttribute("height", renderItem['arguments'][8]);
|
||||
el.setAttribute("x", renderItem['arguments'][5]);
|
||||
el.setAttribute("y", renderItem['arguments'][6]);
|
||||
el.setAttribute("clip-path", "url(#clipId" + clipId + ")");
|
||||
// el.setAttribute("xlink:href", );
|
||||
|
||||
|
||||
el.setAttribute("preserveAspectRatio", "none");
|
||||
|
||||
svg.appendChild(el);
|
||||
|
||||
|
||||
clipId += 1;
|
||||
/*
|
||||
ctx.drawImage(
|
||||
renderItem['arguments'][0],
|
||||
renderItem['arguments'][1],
|
||||
renderItem['arguments'][2],
|
||||
renderItem['arguments'][3],
|
||||
renderItem['arguments'][4],
|
||||
renderItem['arguments'][5],
|
||||
renderItem['arguments'][6],
|
||||
renderItem['arguments'][7],
|
||||
renderItem['arguments'][8]
|
||||
);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
if (storageContext.clip){
|
||||
ctx.restore();
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
_html2canvas.Util.log("html2canvas: Renderer: SVG Renderer done - returning SVG DOM obj");
|
||||
|
||||
return svg;
|
||||
}
|
||||
};
|
||||
|
||||
return methods;
|
||||
|
||||
|
||||
};
|
@ -1,46 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="252.89000pt" width="493.28000pt" version="1.0" y="0.00000000" x="0.00000000" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<linearGradient id="lg0">
|
||||
<stop style="stop-color:#ff0000;stop-opacity:1.0000000" offset="0.00000000"/>
|
||||
<stop style="stop-color:#00ff00;stop-opacity:1.0000000" offset="0.50000000"/>
|
||||
<stop style="stop-color:#0000ff;stop-opacity:1.0000000" offset="1.0000000"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="lg1">
|
||||
<stop style="stop-color:#ff0000;stop-opacity:0.27450982" offset="0.00000000"/>
|
||||
<stop style="stop-color:#ff0000;stop-opacity:1.0000000" offset="1.0000000"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="rd0" fx="550.28571" fy="155.11731" xlink:href="#lg1" gradientUnits="userSpaceOnUse" cy="155.11731" cx="550.28571" gradientTransform="matrix(0.652228,-1.522906,1.403595,0.601129,-26.34767,869.2927)" r="127.00000"/>
|
||||
<radialGradient id="rd1" fx="492.85715" fy="379.50504" xlink:href="#lg3" gradientUnits="userSpaceOnUse" cy="379.50504" cx="492.85715" gradientTransform="matrix(0.944964,4.150569e-2,-4.340623e-2,0.988234,43.59757,-15.99113)" r="184.96443"/>
|
||||
<radialGradient id="rd2" fx="449.12918" fy="345.23175" xlink:href="#lg2" gradientUnits="userSpaceOnUse" cy="345.23175" cx="449.12918" gradientTransform="matrix(1.06455,-4.457048e-3,4.186833e-3,1.000012,-30.43703,1.997764)" r="184.96443"/>
|
||||
<linearGradient id="lg2">
|
||||
<stop style="stop-color:#fa4;stop-opacity:1" offset="0"/>
|
||||
<stop style="stop-color:#c3791f;stop-opacity:1" offset="0.5"/>
|
||||
<stop style="stop-color:#935000;stop-opacity:1" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="lg3">
|
||||
<stop style="stop-color:black;stop-opacity:1" offset="0"/>
|
||||
<stop style="stop-color:black;stop-opacity:1" offset="0.5"/>
|
||||
<stop style="stop-color:black;stop-opacity:1" offset="0.75"/>
|
||||
<stop style="stop-color:black;stop-opacity:0.72164947" offset="0.875"/>
|
||||
<stop style="stop-color:black;stop-opacity:0.50515461" offset="0.9375"/>
|
||||
<stop style="stop-color:black;stop-opacity:0.3298969" offset="0.96875"/>
|
||||
<stop style="stop-color:black;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path d="M300 252.36218C300 307.59065 255.22847 352.36218 200 352.36218 144.77153 352.36218 100 307.59065 100 252.36218 100 197.13371 144.77153 152.36218 200 152.36218 255.22847 152.36218 300 197.13371 300 252.36218L300 252.36218z" style="fill:#00ffff;fill-opacity:0.49999997;fill-rule:evenodd;stroke:#00ffff;stroke-width:4.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000" transform="translate(-91.79890,-143.8324)"/>
|
||||
<path d="M500 252.36218C500 307.59065 455.22847 352.36218 400 352.36218 344.77153 352.36218 300 307.59065 300 252.36218 300 197.13371 344.77153 152.36218 400 152.36218 455.22847 152.36218 500 197.13371 500 252.36218L500 252.36218z" style="fill:#ffff00;fill-opacity:0.49999997;fill-rule:evenodd;stroke:#ffff00;stroke-width:4.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000" transform="translate(-242.7989,-42.83241)"/>
|
||||
<path d="M400 452.36218C400 507.59065 355.22847 552.36218 300 552.36218 244.77153 552.36218 200 507.59065 200 452.36218 200 397.13371 244.77153 352.36218 300 352.36218 355.22847 352.36218 400 397.13371 400 452.36218L400 452.36218z" style="fill:#ff00ff;fill-opacity:0.49999997;fill-rule:evenodd;stroke:#ff00ff;stroke-width:4.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000" transform="translate(-90.79890,-342.8324)"/>
|
||||
<rect style="fill:url(#rd0);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000;stroke-width:4.0000000;stroke-linecap:butt;stroke-miterlimit:4.0000000;stroke-dasharray:8.0000000 4.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000" rx="41.428570" ry="41.428570" transform="translate(6.201104,5.167586)" width="250.00000" y="2.3621826" x="351.00000" height="150.00000"/>
|
||||
<text style="font-size:72px;font-style:oblique;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr;text-anchor:start;fill:#fff;fill-opacity:0.49999997;stroke:#000;stroke-width:3.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:6.0000000 3.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans" xml:space="preserve" transform="translate(6.201104,5.167586)" y="101.34265" x="398.91016"><tspan y="101.34265" x="398.91016">SVG</tspan></text>
|
||||
<g transform="matrix(0.403355,0.000000,0.000000,0.403355,284.7118,53.56855)">
|
||||
<path style="fill:url(#rd1);fill-opacity:1.0000000;stroke:none;stroke-width:4.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000" d="M675.82158 379.50504A182.96443 182.96443 0 1 0 309.89272 379.50504 182.96443 182.96443 0 1 0 675.82158 379.50504z" transform="translate(25.71677,42.14162)"/>
|
||||
<path style="fill:url(#rd2);fill-opacity:1.0000000;stroke:none;stroke-width:4.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000" d="M675.82158 379.50504A182.96443 182.96443 0 1 0 309.89272 379.50504 182.96443 182.96443 0 1 0 675.82158 379.50504z" transform="translate(3.000000,1.000000)"/>
|
||||
<path style="color:#000;fill:#000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:4.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000;marker:none" d="M448.21432 203.83901C450.36313 204.6315 453.75174 205.94795 456.34375 207.71875 458.93576 209.48955 460.70727 211.5991 460.84375 214 461.1565 219.5018 462.73056 224.22855 456.3125 234.21875 449.89444 244.20895 435.16134 259.07637 402.75 282.4375 341.89198 326.30215 327.69756 419.11497 324.82774 445.4561L327.9384 453.22053C327.9384 453.22053 336.06337 335.44254 405.09375 285.6875 437.69027 262.19289 452.72065 247.17079 459.65625 236.375 466.59185 225.57921 465.12192 218.64356 464.84375 213.75 464.60642 209.57479 461.69349 206.55518 458.59375 204.4375 457.315 203.56388 455.94644 202.87002 454.65334 202.2368L448.21432 203.83901z"/>
|
||||
<path style="color:#000;fill:#000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:4.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000;marker:none" d="M509.01528 198.02937C499.53358 209.87282 477.91722 245.5091 465.15625 336.75 449.39628 449.43374 450.70852 546.83082 450.91598 557.84038L454.9375 558.75C454.9375 558.75 452.43678 456.60195 469.125 337.28125 482.74755 239.88008 506.43369 206.85787 513.90048 198.46178 513.90048 198.46178 509.01528 198.02937 509.01528 198.02937z"/>
|
||||
<path style="color:#000;fill:#000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:4.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000;marker:none" d="M556.6875 211.625C547.0438 211.8095 537.01703 214.51544 529.96875 222.90625 520.74474 233.88721 520.91652 245.76284 524.5 256.1875 528.08348 266.61216 534.88069 275.92531 538.96875 282.875 541.20112 286.67003 547.45814 295.57779 555.4375 309.1875 563.41686 322.79721 573.02573 340.97669 581.71875 362.78125 599.10479 406.39038 612.72572 464.47037 601.9375 529.59375 601.9375 529.59375 606.5655 526.08172 606.5655 526.08172 616.26061 461.73706 602.63933 404.42832 585.4375 361.28125 576.65129 339.24295 566.92996 320.8949 558.875 307.15625 550.82004 293.4176 544.35231 284.15204 542.40625 280.84375 538.13746 273.5868 531.59217 264.50677 528.28125 254.875 524.97033 245.24323 524.70586 235.41118 533.03125 225.5 541.18293 215.79562 554.20308 214.66443 565.5625 216.125 576.92192 217.58557 586.26153 221.51972 586.26153 221.51972 586.26153 221.51972 568.49535 212.55885 568.49535 212.55885 567.63548 212.41794 566.98202 212.27046 566.09375 212.15625 563.09277 211.77039 559.90207 211.5635 556.6875 211.625z"/>
|
||||
<path style="color:#000;fill:#000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:4.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.00000000;stroke-opacity:1.0000000;marker:none" d="M458.15625 224.96875C424.33124 226.01594 399.1972 233.81099 381.5 242.40625 376.05652 245.05007 371.36415 247.88263 367.2855 250.51507 362.72383 255.08465 357.48708 260.80582 350.5625 269.40625 350.5625 269.40625 360.3001 257.14641 383.25 246 406.1999 234.85359 442.22471 224.97829 494.53125 230.375 599.18056 241.17215 643.20884 296.98475 675.71875 347 675.71875 347 673.37503 336.37355 673.37503 336.37355 641.03129 288.32441 594.99108 236.69798 494.9375 226.375 481.69006 225.0082 469.43125 224.61969 458.15625 224.96875z"/>
|
||||
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 2.9 KiB |
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* jQuery helper plugin for examples and tests
|
||||
*/
|
||||
(function( $ ){
|
||||
$.fn.html2canvas = function(options) {
|
||||
if (options && options.profile && window.console && window.console.profile && window.location.search !== "?selenium2") {
|
||||
console.profile();
|
||||
}
|
||||
var date = new Date(),
|
||||
html2obj,
|
||||
$message = null,
|
||||
timeoutTimer = false,
|
||||
timer = date.getTime();
|
||||
options = options || {};
|
||||
|
||||
options.onrendered = options.onrendered || function( canvas ) {
|
||||
var $canvas = $(canvas),
|
||||
finishTime = new Date();
|
||||
|
||||
if (options && options.profile && window.console && window.console.profileEnd) {
|
||||
console.profileEnd();
|
||||
}
|
||||
$canvas.addClass("html2canvas")
|
||||
.css({
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0
|
||||
}).appendTo(document.body);
|
||||
|
||||
if (window.location.search !== "?selenium") {
|
||||
$canvas.siblings().toggle();
|
||||
$(window).click(function(){
|
||||
$canvas.toggle().siblings().toggle();
|
||||
throwMessage("Canvas Render " + ($canvas.is(':visible') ? "visible" : "hidden"));
|
||||
});
|
||||
throwMessage('Screenshot created in '+ ((finishTime.getTime()-timer)) + " ms<br />",4000);
|
||||
} else {
|
||||
$canvas.css('display', 'none');
|
||||
}
|
||||
// test if canvas is read-able
|
||||
try {
|
||||
$canvas[0].toDataURL();
|
||||
} catch(e) {
|
||||
if ($canvas[0].nodeName.toLowerCase() === "canvas") {
|
||||
// TODO, maybe add a bit less offensive way to present this, but still something that can easily be noticed
|
||||
alert("Canvas is tainted, unable to read data");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
html2obj = html2canvas(this, options);
|
||||
|
||||
function throwMessage(msg,duration){
|
||||
window.clearTimeout(timeoutTimer);
|
||||
timeoutTimer = window.setTimeout(function(){
|
||||
$message.fadeOut(function(){
|
||||
$message.remove();
|
||||
$message = null;
|
||||
});
|
||||
},duration || 2000);
|
||||
if ($message)
|
||||
$message.remove();
|
||||
$message = $('<div />').html(msg).css({
|
||||
margin:0,
|
||||
padding:10,
|
||||
background: "#000",
|
||||
opacity:0.7,
|
||||
position:"fixed",
|
||||
top:10,
|
||||
right:10,
|
||||
fontFamily: 'Tahoma',
|
||||
color:'#fff',
|
||||
fontSize:12,
|
||||
borderRadius:12,
|
||||
width:'auto',
|
||||
height:'auto',
|
||||
textAlign:'center',
|
||||
textDecoration:'none',
|
||||
display:'none'
|
||||
}).appendTo(document.body).fadeIn();
|
||||
html2obj.log(msg);
|
||||
}
|
||||
};
|
||||
})( jQuery );
|
98
tests/background.html
Normal file
@ -0,0 +1,98 @@
|
||||
<!--
|
||||
* @author Niklas von Hertzen <niklas at hertzen.com>
|
||||
* @created 15.7.2011
|
||||
* @website http://hertzen.com
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Background attribute tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link href="#" type="text/css" rel="stylesheet">
|
||||
<script type="text/javascript" src="../external/jquery-1.6.2.min.js"></script>
|
||||
<script type="text/javascript" src="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
|
||||
$('body').html2canvas({
|
||||
logging:true
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.small div{
|
||||
width:100px;
|
||||
height:100px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.medium div{
|
||||
width:200px;
|
||||
height:200px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.small, .medium{
|
||||
clear:both;
|
||||
}
|
||||
|
||||
div{
|
||||
display:block;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="medium">
|
||||
<div style="background:url(image.jpg);"></div>
|
||||
<div style="background:url(image.jpg) repeat-x;"></div>
|
||||
<div style="background:url(image.jpg) repeat-y;"></div>
|
||||
<div style="background:url(image.jpg) no-repeat;"></div>
|
||||
</div>
|
||||
<div class="small">
|
||||
<div style="background:url(image.jpg);"></div>
|
||||
<div style="background:url(image.jpg) repeat-x;"></div>
|
||||
<div style="background:url(image.jpg) repeat-y;"></div>
|
||||
<div style="background:url(image.jpg) no-repeat;"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="medium">
|
||||
<div style="background:url(image.jpg) center center;"></div>
|
||||
<div style="background:url(image.jpg) repeat-x center center;"></div>
|
||||
<div style="background:url(image.jpg) repeat-y center center;"></div>
|
||||
<div style="background:url(image.jpg) no-repeat center center;"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="small">
|
||||
<div style="background:url(image.jpg) center center;"></div>
|
||||
<div style="background:url(image.jpg) repeat-x center center;"></div>
|
||||
<div style="background:url(image.jpg) repeat-y center center;"></div>
|
||||
<div style="background:url(image.jpg) no-repeat center center;"></div>
|
||||
</div>
|
||||
|
||||
<div class="medium">
|
||||
<div style="background:url(image.jpg) 50px 50px;"></div>
|
||||
<div style="background:url(image.jpg) repeat-x 50px 50px;"></div>
|
||||
<div style="background:url(image.jpg) repeat-y 50px 50px;"></div>
|
||||
<div style="background:url(image.jpg) no-repeat 50px 50px;"></div>
|
||||
</div>
|
||||
|
||||
<div class="medium">
|
||||
|
||||
<div style="background:url(image.jpg) no-repeat -15% 25px;"></div>
|
||||
<div style="background-image:url(image.jpg), url(image2.jpg); background-repeat: repeat-x; background-position: 50px 50px, 100px 100px;"></div>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
120
tests/borders.html
Normal file
@ -0,0 +1,120 @@
|
||||
<!--
|
||||
* @author Niklas von Hertzen <niklas at hertzen.com>
|
||||
* @created 15.7.2011
|
||||
* @website http://hertzen.com
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>z-index tests #2</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link href="#" type="text/css" rel="stylesheet">
|
||||
<script type="text/javascript" src="../external/jquery-1.6.2.min.js"></script>
|
||||
<script type="text/javascript" src="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
|
||||
$('body').html2canvas({
|
||||
logging:true
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
div { font: 12px Arial; }
|
||||
|
||||
span.bold { font-weight: bold; }
|
||||
|
||||
#div2 { z-index: 2; }
|
||||
#div3 { z-index: 1; }
|
||||
#div4 { z-index: 10; }
|
||||
|
||||
#div1,#div3 {
|
||||
height: 80px;
|
||||
position: relative;
|
||||
border: 1px dashed #669966;
|
||||
background-color: #ccffcc;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
#div2 {
|
||||
opacity: 0.8;
|
||||
position: absolute;
|
||||
width: 150px;
|
||||
height: 200px;
|
||||
top: 20px;
|
||||
left: 170px;
|
||||
border: 1px dashed #990000;
|
||||
background-color: #ffdddd;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#div4 {
|
||||
opacity: 0.8;
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 70px;
|
||||
top: 65px;
|
||||
left: 50px;
|
||||
border: 1px dashed #000099;
|
||||
background-color: #ddddff;
|
||||
text-align: left;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
#div5{
|
||||
border: 1px dashed #669966;
|
||||
background-color: #ccffcc;
|
||||
padding-left: 5px;
|
||||
position:relative;
|
||||
margin-bottom:-15px;
|
||||
height:50px;
|
||||
margin-top:10px;
|
||||
|
||||
}
|
||||
|
||||
#div6{
|
||||
border: 1px dashed #000099;
|
||||
background-color: #ddddff;
|
||||
text-align: left;
|
||||
padding-left: 10px;
|
||||
|
||||
}
|
||||
|
||||
</style></head>
|
||||
|
||||
<body>
|
||||
|
||||
<br />
|
||||
|
||||
<div id="div1">
|
||||
<br /><span class="bold">DIV #1</span>
|
||||
<br />position: relative;
|
||||
<div id="div2">
|
||||
<br /><span class="bold">DIV #2</span>
|
||||
<br />position: absolute;
|
||||
<br />z-index: 2;
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div id="div3">
|
||||
<br /><span class="bold">DIV #3</span>
|
||||
<br />position: relative;
|
||||
<br />z-index: 1;
|
||||
<div id="div4">
|
||||
<br /><span class="bold">DIV #4</span>
|
||||
<br />position: absolute;
|
||||
<br />z-index: 10;
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="div5"><br />DIV #5<br />position:relative;<br /></div>
|
||||
|
||||
<div id ="div6"><br />DIV #6<br />position:static;<br /></div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,60 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Background attribute tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style>
|
||||
html {
|
||||
background-color: red;
|
||||
}
|
||||
body {
|
||||
background-color: lime;
|
||||
}
|
||||
.small div{
|
||||
width:100px;
|
||||
height:100px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.medium div{
|
||||
width:200px;
|
||||
height:200px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:20px solid transparent;
|
||||
border-width: 10px 20px 30px 40px;
|
||||
background: green;
|
||||
}
|
||||
|
||||
.small, .medium{
|
||||
clear:both;
|
||||
}
|
||||
|
||||
div{
|
||||
display:block;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="medium">
|
||||
<div style="background:url(../../assets/image.jpg);background-clip: border-box;"></div>
|
||||
<div style="background:url(../../assets/image.jpg);background-clip: padding-box;"></div>
|
||||
<div style="background:url(../../assets/image.jpg);background-clip: content-box;"></div>
|
||||
<div style="background:url(../../assets/image.jpg);"></div>
|
||||
</div>
|
||||
|
||||
<div class="medium">
|
||||
<div style="background-clip: border-box;"></div>
|
||||
<div style="background-clip: padding-box;"></div>
|
||||
<div style="background-clip: content-box;"></div>
|
||||
<div style=""></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,52 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Background attribute tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style>
|
||||
html {
|
||||
background-color: red;
|
||||
}
|
||||
body {
|
||||
background-color: lime;
|
||||
}
|
||||
.small div{
|
||||
width:100px;
|
||||
height:100px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.medium div{
|
||||
width:200px;
|
||||
height:200px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.small, .medium{
|
||||
clear:both;
|
||||
}
|
||||
|
||||
div{
|
||||
display:block;
|
||||
}
|
||||
|
||||
.encoded {
|
||||
background:url("data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCABLAEsDAREAAhEBAxEB/8QAHAAAAgMBAQEBAAAAAAAAAAAABQcEBggCAwAJ/8QANxAAAgECBQEHAQUIAwEAAAAAAQIDBBEABQYSITEHExQiQVFhcTKBkbHBCCNCUnLR4fAWYqLx/8QAGwEAAQUBAQAAAAAAAAAAAAAAAQIDBAUGAAf/xAAzEQACAgECAwQHCAMAAAAAAAAAAQIDEQQhEjFBIlFhcRMUgZGhsdEFFSNCUsHh8DKi8f/aAAwDAQACEQMRAD8AxREirbfKlv6rYxDz0R6mmj2eohpqrLKmGVTJTVsEpG65sHF8dBSakpLmn8hq5pxTXRo0DlaCn1dB7eJZfxxD0b/FiyFqVmmQ1Yo/KMaRFBIj5tCTFSG3SsgP/sf3x0t0JTJtLTlJa0FSP31+R/0TCcYG8nM0Q9sLAQJoRzgnECoiFjggB7RC5wsSZHTLaGCQpJBSq68EbQ1sUjst72bdU1dy9x1mlPQJlNQY0p+9Rd67YwDcG/HGBVK12JPOPMF1darbUVt4GgoazdmeW1YNxKaea/8AUoJxVafsTj4P9xm5cVcvJjjhljjlRZDtBPt1xqlzMu3tsNjSulMrziigkVUkUOHK9RcdD8Ys6owcStsnJMsFV2ZUrxVDRqQ0luSL9P8AH5YcdUWhtWtC91T2e1mWRPUQx740BLKt7/X6YhTqcd0S4WKWxQZhiOPA+ccYICAy3Y4UAyXS/uwFXLGFv5kX++KCWHu5m6i3y4SbI7y0k0bZbZHQqTtT2/qw3FRUk1P5/QVJtxa4X8PqNHIanxmndMzg+Z6KEc+6kqfyxG4MXuPiyFJ4qcn3F5o9RGrzPbI5aRz6np7D2GLpSbfiZ9xWMD20Fq5MlgpF72PdNIyGE8OFFvMPjn7/ALsWlE3FIrbYcTH5keaw11MtnVz063xZqWSvccMkZhRwT08m4KRY3BwibSW4uCeTJ+qKA5PnuYURBXuZmVQ/Xbe6n8CMVTWGWXQATOCCLjBAQXbzHphQkyTS5XE1HTXpttTtPfB5bruvxt+LdcUc7e08PY3dcez2luTIsm3GwjhF+OW/xhl3eLHuHwLpo1pn0lkrRh5no2qICkSGRmZJSQAo6khhxhmxS9azFc8P3kLsqiUZeQ3dPafhmrFkU7HUh3Exsyi9269LeuL2Me0ZWUsIM6p7EKjtkzTLXi1XVaWaEvfwSkmqJZdq7Qy9LdSeOeD6WlSRAm8YbNDN2f6ry6lpqXRGq6RqjLXjapgzaiM3i4woPdK6sCpYXs3NuOuJXBjkR3JNbjRy+KvkpF8bEaaV1tYi5/8AuI0k2tx1NLkYQ/aB1XmucdrGeHLNQ5jl+X07ikjiptiITGNrNfaSSWvyTf7gMUt2olGxxjyRe0Uw9GnOOWxXyVuoVLM+rc7kBvYeIC2/BcNeszew+qK1+UGTVmdGRj/yjPV+PGH+2HVqJ94PRV/pQtos+1SPs0WVi/S5kP64S9PpespfAlLUaz9Efj9QtkEmuc/roaajgycB2AaRo5NsY9WJB6DHeraVvCcm/Z9BM9Vq4rMlFL2/Dc0dp7L4dO5eKWl6k7pJtoVpGtyxA6dOgxIqpVawipuvldLMgtRzIjbDJsBYeW32sSlAiNkLtI7Y6nRkMcOWGeKYKqrMsO8Ru91Qkeo3bfKP1wpN8XDEXCtSWWGv2Le1nXk2qJn1VXjNVrHWJJpy3euIRtLcKAFAO0X6k8Di+Jzmk4xiQ5UWRUnYsGvO23thyvs60bUVIq0GcV1O4yykU3ldyNvegeiITck8XFuThOqvhRXxN7vkDSUTvsUUtlzPzdzqecS940zOzkvI7HlmuSxPyeuMfF5e/M1/CkerKFiaZQZIiN19wJ+oGE5T2Ow2QGkhc7u7fn6YWmDhYMnyDLGBanrp43JG8TQhx09CtrYs5aaPSTIEPtKf54L2PHzyXrRmVQZTlJZFQyyctIqlbj0HOHKqvRrfdkbUah3yzyXcWnK6lK4Ps+0h2snqDiXFZITeA/leTSV1ZGii537DZbgAjn64kRhljbkkhqt+zkmo6ekLx0s61ZNJJT1se5GABNn4IN/0BxIlpctSi8MajqOcZLKG32e9immtA6berly+nVqaF3ip4dyxR2UndybliR1J4Fhh6FSj2p7sZna32Y8jM+faKzjU2YNmWZ54tZmFSAZJ54mdiB0A6WUDoBYYoZ6C62XHZYm34MtofaNNceCFbS80B6jskrWRQmb0e8g3D07gLb7zfCPuufSa9zF/elfWD96Kzn2iZ8mjqFmmjd46hoN5tGsjKBu2BjubhlPAsAet8Vl+mlTlt9f7jr+xa1aiNuMLpn+9Clyaan3tt7vbfjzjEbLJWUUxqqxBtdR6e+NJgy/IZmlKiTMdPpO8RiuWsL/aAPUYUlsBvvO8glmi1LHGEURzAhh6gAXGFxW4mT2HbpOhTxSSOGWNrbghBJ+behxOgiLKRobSWo6fJKGE11YYYmO9TI/mP8J2jkkm1uP1xNTSW5F3b2CGp9UxHTGZVCkmnaMokbdTu8vP44alPIBCxkKFHJsStwfS5FsN5AfSSkpMyXEaAFiebLwCfxOCAomrshgGofFzw0UVPVoHlqJgu+NhZJG5IFhwbnnzcemKfVVQVnHJJZ69f748zQaO6cqlFNvG2Onev+chT1MEwqZfDyQdxuOwVDhZAL9CPjpjOvbkzQLxFk8TpIA6kpe7WHpjTYMrnI49KVVHmGX0cdOsnhwLI5Ujc3sB1Nr9elz64dSBkFZ+9To7PaatqwsNNFUhWk3G0YY28xP8PNyfS+OinGRzawa07E4IaySCaVVeOQdOoBHS/vixqIFnMtnb8tatHpxcpjgepjqHlKzOYwU2bSoYA26g9PTBtWcYG4y4XuU4Z9mE+TJl88cMUJ2FlDFzcG9gbDi+GEmFyT5AWSInvFFyFJHHXp/nBE5PHLA0Ek9M7EtNEYw59T8/76YMe46W+5W9dd+cm76IWMDhZbRxuAkg2tuDgggMFuBzyeuIesjmviXTwT2fmWOhklY4Pr5815Cxly+GRwxy+lclQdypMoPA5spKj7iR7YoJVtPHAv8AZfLK9xpI2Jr/ACfwItT2YTToVjCsTx5W639Mah0dxkVbgjZVojV+nqhXyeKOeON9yxzuFHwASeAOTb3OBGqaFemj1Gpn2VVuudD51kdRkcFDPWqIvE1dTG7qLLd1CX5JDDn64kcDwMuxE3sNoNWdnarltd3FZRx37mYVQOxFAsGH2r9eelrYEISiGVkZLI3M/wBRTallp5p9qLGuyNAb2FuTf5OHWskdsATRb1L2Fgf9/XCcHZIrRHxJHsdxHryPyIwMCiPLAwa9gHS4t7m/GOwcQ66natgqaSQeWqjaJSSP4hcG5vYggdQbH3wmUOOLj3jlcuCal3CIqWplqJAaWGNtxJSSdkYH1upVbG/wMZnixtlL2r+PkazhT33+P8jGy5iViYnzWBv841hjwplh3RwX9SXPyS2OQcBNpWpYZWiO096E6X8u61vwxyE9AplEjLPmLBjdQFHwOOMFdRL5BOjdmijJJJAU/wC/gMcgs6pnLIpJuTUAH6XtgndWjwy1Qc1qeP5fzwFzO6EOR28dSDcfPVhW56j93x+eB1CBdXVEtLmmWiJzGDOQbH03DCJbNBXJiU1zUyUGtc+p6dzDBFXzqkacBQJDYDGV1F9kLpxi9k38zbaaqE6ISkt2kf/Z");
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="medium">
|
||||
<div class="encoded"></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,105 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Background attribute tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style>
|
||||
html {
|
||||
background-color: red;
|
||||
}
|
||||
body {
|
||||
background-color: lime;
|
||||
}
|
||||
.small div{
|
||||
width:100px;
|
||||
height:100px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.medium div{
|
||||
width:200px;
|
||||
height:200px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.small, .medium{
|
||||
clear:both;
|
||||
}
|
||||
|
||||
div{
|
||||
display:block;
|
||||
}
|
||||
|
||||
.linearGradient {
|
||||
/*background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(255, 0, 0)), to(rgb(0, 0, 255)));*/
|
||||
background: -webkit-linear-gradient(top left, #f00, #00f, #BADA55, rgba(0, 0, 255,0.5));
|
||||
background: -moz-linear-gradient(top right, #f00, #00f, #BADA55, rgba(0, 0, 255,0.5));
|
||||
}
|
||||
|
||||
.linearGradient2 {
|
||||
background: -webkit-gradient(linear, 0% 0, 0% 100%, from(rgb(252, 252, 252)), to(rgb(232, 232, 232)));
|
||||
}
|
||||
|
||||
.linearGradient3 {
|
||||
/* FF 3.6+ */
|
||||
background: -moz-linear-gradient(left, #ff0000, #ffff00, #00ff00);
|
||||
/* Chrome,Safari4+ */
|
||||
background: -webkit-gradient(linear, left top, right top, color-stop(#ff0000), color-stop(#ffff00), color-stop(#00ff00));
|
||||
/* Chrome 10+, Safari 5.1+ */
|
||||
background: -webkit-linear-gradient(left, #ff0000, #ffff00, #00ff00);
|
||||
/* Opera 11.10+ */
|
||||
background: -o-linear-gradient(left, #ff0000, #ffff00, #00ff00);
|
||||
/* IE 10+ */
|
||||
background: -ms-linear-gradient(left, #ff0000, #ffff00, #00ff00);
|
||||
/* W3C */
|
||||
background: linear-gradient(left, #ff0000, #ffff00, #00ff00);
|
||||
}
|
||||
|
||||
.linearGradient4 {
|
||||
/* FF 3.6+ */
|
||||
background: -moz-linear-gradient(left, #cedbe9 0%, #aac5de 17%, #6199c7 50%, #3a84c3 51%, #419ad6 59%, #4bb8f0 71%, #3a8bc2 84%, #26558b 100%);
|
||||
/* Chrome, Safari 4+ */
|
||||
background: -webkit-gradient(linear, left top, right top, color-stop(0%, #cedbe9), color-stop(17%, #aac5de), color-stop(50%, #6199c7), color-stop(51%, #3a84c3), color-stop(59%, #419ad6), color-stop(71%, #4bb8f0), color-stop(84%, #3a8bc2), color-stop(100%, #26558b));
|
||||
/* Chrome 10+, Safari 5.1+ */
|
||||
background: -webkit-linear-gradient(left, #cedbe9 0%, #aac5de 17%, #6199c7 50%, #3a84c3 51%, #419ad6 59%, #4bb8f0 71%, #3a8bc2 84%, #26558b 100%);
|
||||
/* Opera 11.10+ */
|
||||
background: -o-linear-gradient(left, #cedbe9 0%, #aac5de 17%, #6199c7 50%, #3a84c3 51%, #419ad6 59%, #4bb8f0 71%, #3a8bc2 84%, #26558b 100%);
|
||||
/* IE10+ */
|
||||
background: -ms-linear-gradient(left, #cedbe9 0%, #aac5de 17%, #6199c7 50%, #3a84c3 51%, #419ad6 59%, #4bb8f0 71%, #3a8bc2 84%, #26558b 100%);
|
||||
/* W3C */
|
||||
background: linear-gradient(left, #cedbe9 0%, #aac5de 17%, #6199c7 50%, #3a84c3 51%, #419ad6 59%, #4bb8f0 71%, #3a8bc2 84%, #26558b 100%);
|
||||
}
|
||||
|
||||
.linearGradient5 {
|
||||
/* FF 3.6+ */
|
||||
background: -moz-linear-gradient(top, #f0b7a1 0%, #8c3310 50%, #752201 51%, #bf6e4e 100%);
|
||||
/* Chrome, Safari 4+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f0b7a1), color-stop(50%, #8c3310), color-stop(51%, #752201), color-stop(100%, #bf6e4e));
|
||||
/* Chrome 10+, Safari 5.1+ */
|
||||
background: -webkit-linear-gradient(top, #f0b7a1 0%, #8c3310 50%, #752201 51%, #bf6e4e 100%);
|
||||
/* Opera 11.10+ */
|
||||
background: -o-linear-gradient(top, #f0b7a1 0%, #8c3310 50%, #752201 51%, #bf6e4e 100%);
|
||||
/* IE 10+ */
|
||||
background: -ms-linear-gradient(top, #f0b7a1 0%, #8c3310 50%, #752201 51%, #bf6e4e 100%);
|
||||
/* W3C */
|
||||
background: linear-gradient(top, #f0b7a1 0%, #8c3310 50%, #752201 51%, #bf6e4e 100%);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="medium">
|
||||
<div class="linearGradient"> </div>
|
||||
<div class="linearGradient2"> </div>
|
||||
<div class="linearGradient3"> </div>
|
||||
<div class="linearGradient4"> </div>
|
||||
<div class="linearGradient5"> </div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,50 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Background attribute tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style>
|
||||
html {
|
||||
background-color: red;
|
||||
}
|
||||
body {
|
||||
background-color: lime;
|
||||
}
|
||||
.small div{
|
||||
width:100px;
|
||||
height:100px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.medium div{
|
||||
width:200px;
|
||||
height:200px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.small, .medium{
|
||||
clear:both;
|
||||
}
|
||||
|
||||
div{
|
||||
display:block;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="medium">
|
||||
<div style="background-image:url(../../assets/image.jpg), url(../../assets/image2.jpg); background-repeat: repeat-x; background-position: 50px 50px, 100px 130px;"></div>
|
||||
<div style="background-image:url(../../assets/image.jpg), url(../../assets/image2.jpg); background-repeat: repeat-x; background-position: 50px 50px, 20px -20px;"></div>
|
||||
<div style="background-image:url(../../assets/image.jpg), url(../../assets/image2.jpg); background-repeat: repeat-x; background-position: 50px 50px, 450px 100px;"></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,66 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Background attribute tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style>
|
||||
html {
|
||||
background-color: red;
|
||||
}
|
||||
body {
|
||||
background-color: lime;
|
||||
}
|
||||
.small div{
|
||||
width:100px;
|
||||
height:100px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.medium div{
|
||||
width:200px;
|
||||
height:200px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.small, .medium{
|
||||
clear:both;
|
||||
}
|
||||
|
||||
div{
|
||||
display:block;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="medium">
|
||||
<div style='background:url("../../assets/image.jpg") center center;'></div>
|
||||
<div style="background:url('../../assets/image.jpg') repeat-x center center;"></div>
|
||||
<div style="background:url(../../assets/image.jpg) repeat-y center center;"></div>
|
||||
<div style="background:url(../../assets/image.jpg) no-repeat center center;"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="small">
|
||||
<div style="background:url(../../assets/image.jpg) center center;"></div>
|
||||
<div style="background:url(../../assets/image.jpg) repeat-x center center;"></div>
|
||||
<div style="background:url(../../assets/image.jpg) repeat-y center center;"></div>
|
||||
<div style="background:url(../../assets/image.jpg) no-repeat center center;"></div>
|
||||
</div>
|
||||
|
||||
<div class="medium">
|
||||
<div style="background:url(../../assets/image.jpg) -15% 25px;"></div>
|
||||
<div style="background:url(../../assets/image.jpg) repeat-x 50px 50px;"></div>
|
||||
<div style="background:url(../../assets/image.jpg) repeat-y 50px 50px;"></div>
|
||||
<div style="background:url(../../assets/image.jpg) no-repeat 50px 50px;"></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,161 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Background attribute tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style>
|
||||
html {
|
||||
background-color: red;
|
||||
}
|
||||
body {
|
||||
background-color: lime;
|
||||
}
|
||||
.small div{
|
||||
width:100px;
|
||||
height:100px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.medium div{
|
||||
width:200px;
|
||||
height:200px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.small, .medium{
|
||||
clear:both;
|
||||
}
|
||||
|
||||
div{
|
||||
display:block;
|
||||
}
|
||||
|
||||
.radialGradient {
|
||||
/* FF 3.6+ */
|
||||
background: -moz-radial-gradient(center, ellipse cover, #959595 0%, #0d0d0d 48%, #2f7bd8 50%, #0a0a0a 64%, #4e4e4e 80%, #383838 87%, #1b1b1b 100%);
|
||||
/* Chrome, Safari 4+ */
|
||||
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#959595), color-stop(48%,#0d0d0d), color-stop(50%,#2f7bd8), color-stop(64%,#0a0a0a), color-stop(80%,#4e4e4e), color-stop(87%,#383838), color-stop(100%,#1b1b1b));
|
||||
/* Chrome 10+, Safari 5.1+ */
|
||||
background: -webkit-radial-gradient(center, ellipse cover, #959595 0%, #0d0d0d 48%,#2f7bd8 50%,#0a0a0a 64%,#4e4e4e 80%,#383838 87%,#1b1b1b 100%);
|
||||
/* Opera 12+ */
|
||||
background: -o-radial-gradient(center, ellipse cover, #959595 0%, #0d0d0d 48%,#2f7bd8 50%,#0a0a0a 64%,#4e4e4e 80%,#383838 87%,#1b1b1b 100%);
|
||||
/* IE 10+ */
|
||||
background: -ms-radial-gradient(center, ellipse cover, #959595 0%,#0d0d0d 48%,#2f7bd8 50%,#0a0a0a 64%,#4e4e4e 80%,#383838 87%,#1b1b1b 100%);
|
||||
/* W3C */
|
||||
background: radial-gradient(center, ellipse cover, #959595 0%,#0d0d0d 48%,#2f7bd8 50%,#0a0a0a 64%,#4e4e4e 80%,#383838 87%,#1b1b1b 100%);
|
||||
}
|
||||
|
||||
.radialGradient2 {
|
||||
/* thx to https://twitter.com/#!/markjmclaren/status/13067366701 */
|
||||
|
||||
background-color: #FFF;
|
||||
|
||||
background-image:
|
||||
-webkit-gradient(radial, 45 45, 10, 52 50, 30, from(#A7D30C), to(rgba(1,159,98,0)), color-stop(90%, #019F62)),
|
||||
-webkit-gradient(radial, 105 105, 20, 112 120, 50, from(#ff5f98), to(rgba(255,1,136,0)), color-stop(75%, #ff0188)),
|
||||
-webkit-gradient(radial, 95 15, 15, 102 20, 40, from(#00c9ff), to(rgba(0,201,255,0)), color-stop(80%, #00b5e2)),
|
||||
-webkit-gradient(radial, 0 150, 50, 0 140, 90, from(#f4f201), to(rgba(228, 199,0,0)), color-stop(80%, #e4c700));
|
||||
|
||||
background-image:
|
||||
-moz-radial-gradient(42px 42px, circle farthest-corner, #A7D30C 0%, #A7D30C 3%, rgba(1,159,98,0) 11%),
|
||||
-moz-radial-gradient(45px 45px, circle farthest-corner, #019F62 0%, #019F62 13%, rgba(255,255,255,0) 16%, rgba(255,255,255,0) 100%),
|
||||
|
||||
-moz-radial-gradient(102px 102px, circle farthest-corner, #ff5f98 0%, #ff5f98 15%, rgba(255,1,136,0) 27%),
|
||||
-moz-radial-gradient(105px 105px, circle farthest-corner, #FF0188 0%, #FF0188 28%, rgba(255,255,255,0) 32%, rgba(255,255,255,0) 100%),
|
||||
|
||||
-moz-radial-gradient(92px 12px, circle farthest-corner, #00c9ff 0%, #00c9ff 10%, rgba(0,181,226,0) 26%),
|
||||
-moz-radial-gradient(95px 15px, circle farthest-corner, #00b5e2 0%, #00b5e2 28%, rgba(255,255,255,0) 31%, rgba(255,255,255,0) 100%),
|
||||
|
||||
-moz-radial-gradient(0px 150px, circle farthest-corner, #f4f201 0%, #f4f201 25%, rgba(228,199,0,0) 45%),
|
||||
-moz-radial-gradient(0px 150px, circle farthest-corner, #e4c700 0%, #e4c700 47%, rgba(255,255,255,0) 50%, rgba(255,255,255,0) 100%);
|
||||
}
|
||||
|
||||
.radialGradient3 {
|
||||
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%);
|
||||
background: -o-radial-gradient(75% 19%, ellipse closest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(75% 19%, ellipse closest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(75% 19%, ellipse closest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
}
|
||||
|
||||
.radialGradient4 {
|
||||
background: -moz-radial-gradient(75% 19%, ellipse closest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(75% 19%, ellipse closest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -o-radial-gradient(75% 19%, ellipse closest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(75% 19%, ellipse closest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(75% 19%, ellipse closest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
}
|
||||
.radialGradient5 {
|
||||
background: -moz-radial-gradient(75% 19%, ellipse farthest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(75% 19%, ellipse farthest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -o-radial-gradient(75% 19%, ellipse farthest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(75% 19%, ellipse farthest-side, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(75% 19%, ellipse farthest-side, #ababab, #0000ff 33%,#991f1f 100%)
|
||||
}
|
||||
.radialGradient6 {
|
||||
background: -moz-radial-gradient(75% 19%, ellipse farthest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(75% 19%, ellipse farthest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -o-radial-gradient(75% 19%, ellipse farthest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(75% 19%, ellipse farthest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(75% 19%, ellipse farthest-corner, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
}
|
||||
.radialGradient7 {
|
||||
background: -moz-radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -o-radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(75% 19%, circle contain, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
}
|
||||
.radialGradient8 {
|
||||
background: -moz-radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -o-radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(75% 19%, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
}
|
||||
.radialGradient9 {
|
||||
background: -moz-radial-gradient(right 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(right 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -o-radial-gradient(right 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(right 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(right 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
}
|
||||
.radialGradient10 {
|
||||
background: -moz-radial-gradient(left 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(left 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -o-radial-gradient(left 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(left 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(left 19%, ellipse cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
}
|
||||
.radialGradient11 {
|
||||
background: -moz-radial-gradient(left top, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -webkit-radial-gradient(left top, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -o-radial-gradient(left top, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: -ms-radial-gradient(left top, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
background: radial-gradient(left top, circle cover, #ababab, #0000ff 33%,#991f1f 100%);
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="medium">
|
||||
<div class="radialGradient"> </div>
|
||||
<div class="radialGradient2"> </div>
|
||||
<div class="radialGradient3"> </div>
|
||||
<div class="radialGradient4"> </div>
|
||||
<div class="radialGradient5"> </div>
|
||||
<div class="radialGradient6"> </div>
|
||||
<div class="radialGradient7"> </div>
|
||||
<div class="radialGradient8"> </div>
|
||||
<div class="radialGradient9"> </div>
|
||||
<div class="radialGradient10"> </div>
|
||||
<div class="radialGradient11"> </div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,57 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Background attribute tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style>
|
||||
html {
|
||||
background-color: red;
|
||||
}
|
||||
body {
|
||||
background-color: lime;
|
||||
}
|
||||
.small div{
|
||||
width:100px;
|
||||
height:100px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.medium div{
|
||||
width:200px;
|
||||
height:200px;
|
||||
float:left;
|
||||
margin:10px;
|
||||
border:1px solid #000;
|
||||
}
|
||||
|
||||
.small, .medium{
|
||||
clear:both;
|
||||
}
|
||||
|
||||
div{
|
||||
display:block;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="medium">
|
||||
<div style="background:url(../../assets/image.jpg);"></div>
|
||||
<div style="background:url(../../assets/image.jpg) repeat-x;"></div>
|
||||
<div style="background:url(../../assets/image.jpg) repeat-y;"></div>
|
||||
<div style="background:url(../../assets/image.jpg) no-repeat;"></div>
|
||||
</div>
|
||||
<div class="small">
|
||||
<div style="background:url(../../assets/image.jpg);"></div>
|
||||
<div style="background:url(../../assets/image.jpg) repeat-x;"></div>
|
||||
<div style="background:url(../../assets/image.jpg) repeat-y;"></div>
|
||||
<div style="background:url(../../assets/image.jpg) no-repeat;"></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,47 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Borders tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
div {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
display: inline-block;
|
||||
margin: 10px;
|
||||
background:#6F428C;
|
||||
border-style: dashed;
|
||||
}
|
||||
|
||||
.box1 {
|
||||
border-width: 1px;
|
||||
border-color: #00b5e2;
|
||||
}
|
||||
|
||||
.box2 {
|
||||
border-width: 3px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.box3 {
|
||||
border-width: 10px;
|
||||
}
|
||||
|
||||
.box4 {
|
||||
border-width: 50px;
|
||||
border-color: green;
|
||||
}
|
||||
|
||||
html {
|
||||
background: #3a84c3;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box1"> </div>
|
||||
<div class="box2"> </div>
|
||||
<div class="box3"> </div>
|
||||
<div class="box4"> </div>
|
||||
</body>
|
||||
</html>
|
@ -1,47 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Borders tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
div {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
display: inline-block;
|
||||
margin: 10px;
|
||||
background:#6F428C;
|
||||
border-style: dotted;
|
||||
}
|
||||
|
||||
.box1 {
|
||||
border-width: 1px;
|
||||
border-color: #00b5e2;
|
||||
}
|
||||
|
||||
.box2 {
|
||||
border-width: 3px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.box3 {
|
||||
border-width: 10px;
|
||||
}
|
||||
|
||||
.box4 {
|
||||
border-width: 50px;
|
||||
border-color: green;
|
||||
}
|
||||
|
||||
html {
|
||||
background: #3a84c3;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box1"> </div>
|
||||
<div class="box2"> </div>
|
||||
<div class="box3"> </div>
|
||||
<div class="box4"> </div>
|
||||
</body>
|
||||
</html>
|
@ -1,47 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Borders tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
div {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
display: inline-block;
|
||||
margin: 10px;
|
||||
background:#6F428C;
|
||||
border-style:double;
|
||||
}
|
||||
|
||||
.box1 {
|
||||
border-width: 1px;
|
||||
border-color: #00b5e2;
|
||||
}
|
||||
|
||||
.box2 {
|
||||
border-width: 3px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.box3 {
|
||||
border-width: 10px;
|
||||
}
|
||||
|
||||
.box4 {
|
||||
border-width: 50px;
|
||||
border-color: green;
|
||||
}
|
||||
|
||||
html {
|
||||
background: #3a84c3;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box1"> </div>
|
||||
<div class="box2"> </div>
|
||||
<div class="box3"> </div>
|
||||
<div class="box4"> </div>
|
||||
</body>
|
||||
</html>
|
@ -1,60 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Borders tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
div {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
display: inline-block;
|
||||
margin: 10px;
|
||||
background:#6F428C;
|
||||
border-style: solid;
|
||||
border-radius: 50px;
|
||||
}
|
||||
|
||||
.box1 {
|
||||
border-width: 1px;
|
||||
border-left-color: #00b5e2;
|
||||
border-top-color: red;
|
||||
border-right-color: green;
|
||||
}
|
||||
|
||||
.box2 {
|
||||
border-width: 3px;
|
||||
border-left-color: #00b5e2;
|
||||
border-top-color: red;
|
||||
border-right-color: green;
|
||||
}
|
||||
|
||||
.box3 {
|
||||
border-width: 10px;
|
||||
border-left-color: transparent;
|
||||
border-top-color: red;
|
||||
border-right-color: green;
|
||||
}
|
||||
|
||||
.box4 {
|
||||
border-width: 50px;
|
||||
border-left-color: transparent;
|
||||
border-top-color: red;
|
||||
border-top-width: 10px;
|
||||
border-right-color: green;
|
||||
border-bottom-right-radius: 190px;
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
html {
|
||||
background: #3a84c3;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box1"> </div>
|
||||
<div class="box2"> </div>
|
||||
<div class="box3"> </div>
|
||||
<div class="box4"> </div>
|
||||
</body>
|
||||
</html>
|
@ -1,47 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Borders tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
div {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
display: inline-block;
|
||||
margin: 10px;
|
||||
background:#6F428C;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.box1 {
|
||||
border-width: 1px;
|
||||
border-color: #00b5e2;
|
||||
}
|
||||
|
||||
.box2 {
|
||||
border-width: 3px;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.box3 {
|
||||
border-width: 10px;
|
||||
}
|
||||
|
||||
.box4 {
|
||||
border-width: 50px;
|
||||
border-color: green;
|
||||
}
|
||||
|
||||
html {
|
||||
background: #3a84c3;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box1"> </div>
|
||||
<div class="box2"> </div>
|
||||
<div class="box3"> </div>
|
||||
<div class="box4"> </div>
|
||||
</body>
|
||||
</html>
|
@ -1,22 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Inline text in the top element</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../test.js"></script>
|
||||
<style>
|
||||
span {
|
||||
color:blue;
|
||||
}
|
||||
p {
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
Some inline text <span> followed by text in span </span> followed by more inline text.
|
||||
<p>Then a block level element.</p>
|
||||
Then more inline text.
|
||||
</body>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>iframe test</title>
|
||||
<script type="text/javascript" src="../test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="http://experiments.hertzen.com/csstree/" width="500"></iframe>
|
||||
</body>
|
||||
</html>
|
@ -1,27 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Image tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<script type="text/javascript">
|
||||
function setUp() {
|
||||
if ($('#testcanvas')[0].getContext) {
|
||||
var ctx = $('#testcanvas')[0].getContext('2d');
|
||||
|
||||
ctx.fillStyle = "rgb(200,0,0)";
|
||||
ctx.fillRect (10, 10, 55, 50);
|
||||
|
||||
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
|
||||
ctx.fillRect (30, 30, 55, 50);
|
||||
} else {
|
||||
$('#testcanvas').remove();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="testcanvas" style="width:700px;height:300px;"></canvas>
|
||||
</body>
|
||||
</html>
|
@ -1,21 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>External content tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
|
||||
<base href="http://www.google.com/" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>External image</h1>
|
||||
<img src="http://www.google.com/logos/2011/gregormendel11-hp.jpg" style="border:5px solid black;" />
|
||||
|
||||
<h1>External image (using <base> href)</h1>
|
||||
<img src="/logos/2011/gregormendel11-res.jpg" />
|
||||
|
||||
<h1>External image (CORS)</h1>
|
||||
<img src="http://publishmydata.com/assets/home/blue_bg.png" />
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,13 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Image tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
Image without src attribute, should not crash:
|
||||
<img style="width:50px;height:50px;border:1px solid red;display:block;" />
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,26 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Image tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<img src="../../assets/image.jpg" />
|
||||
<img src="../../assets/image.jpg" style="width:50px;height:400px;" />
|
||||
<img src="../../assets/image.jpg" style="width:500px;" />
|
||||
<img src="../../assets/image.jpg" style="width:500px;height:40px;" />
|
||||
|
||||
|
||||
<img src="../../assets/image.jpg" style="padding:20px;border:5px solid black;" />
|
||||
|
||||
<img src="../../assets/image.jpg" style="padding-bottom:20px;border-top:5px solid black;clear:both;" />
|
||||
|
||||
|
||||
<img src="../../assets/image.jpg" style="padding-top:20px;border-top:5px solid black;clear:both;width:50px;" />
|
||||
<img src="../../assets/image.jpg" style="padding-top:20px;border-top:5px solid black;clear:both;width:50px;height:25px;" />
|
||||
|
||||
<img src="../../assets/image.jpg" style="width:0px;height:0px;border:1px solid black" />
|
||||
<img src="../../assets/image.jpg" style="width:0px;height:0px;" />
|
||||
</body>
|
||||
</html>
|
@ -1,12 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Image tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
SVG taints image:<br /> <!-- http://fi.wikipedia.org/wiki/Tiedosto:Svg.svg -->
|
||||
<img src="../../assets/image.svg" />
|
||||
</body>
|
||||
</html>
|
@ -1,57 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>List tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function setUp() {
|
||||
var supportedTypes = ["decimal","decimal-leading-zero","upper-roman","lower-roman","lower-alpha","upper-alpha"];
|
||||
for (var i = 1;i<=100;i++){
|
||||
$('#dynamic').append($('<li />').text(i).css('list-style-type',supportedTypes[1]));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#dynamic{
|
||||
list-style-type:decimal;
|
||||
list-style-position: inside;
|
||||
font-size:20px;
|
||||
line-height:50px;
|
||||
|
||||
}
|
||||
|
||||
.small{
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.medium{
|
||||
font-size:18px;
|
||||
}
|
||||
.large{
|
||||
font-size:24px;
|
||||
}
|
||||
div{
|
||||
float:left;
|
||||
}
|
||||
h2 {
|
||||
clear:both;
|
||||
}
|
||||
li{
|
||||
border:1px solid black;
|
||||
width:100px;
|
||||
margin:0;
|
||||
}
|
||||
ol{
|
||||
margin:0;
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<ol id="dynamic"></ol>
|
||||
</body>
|
||||
</html>
|
@ -1,59 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>List tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function setUp() {
|
||||
var supportedTypes = ["decimal","decimal-leading-zero","upper-roman","lower-roman","lower-alpha","upper-alpha"];
|
||||
for (var i = 1;i<=100;i++){
|
||||
$('#dynamic').append($('<li />').text(i).css('list-style-type',supportedTypes[0]));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#dynamic{
|
||||
list-style-type:decimal;
|
||||
list-style-position: inside;
|
||||
font-size:20px;
|
||||
line-height:50px;
|
||||
|
||||
}
|
||||
|
||||
.small{
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.medium{
|
||||
font-size:18px;
|
||||
}
|
||||
.large{
|
||||
font-size:24px;
|
||||
}
|
||||
div{
|
||||
float:left;
|
||||
}
|
||||
h2 {
|
||||
clear:both;
|
||||
}
|
||||
li{
|
||||
border:1px solid black;
|
||||
width:100px;
|
||||
margin:0;
|
||||
}
|
||||
ol{
|
||||
margin:0;
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<ol id="dynamic"></ol>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,59 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>List tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function setUp() {
|
||||
var supportedTypes = ["decimal","decimal-leading-zero","upper-roman","lower-roman","lower-alpha","upper-alpha"];
|
||||
for (var i = 1;i<=100;i++){
|
||||
$('#dynamic').append($('<li />').text(i).css('list-style-type',supportedTypes[4]));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#dynamic{
|
||||
list-style-type:decimal;
|
||||
list-style-position: inside;
|
||||
font-size:20px;
|
||||
line-height:50px;
|
||||
|
||||
}
|
||||
|
||||
.small{
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.medium{
|
||||
font-size:18px;
|
||||
}
|
||||
.large{
|
||||
font-size:24px;
|
||||
}
|
||||
div{
|
||||
float:left;
|
||||
}
|
||||
h2 {
|
||||
clear:both;
|
||||
}
|
||||
li{
|
||||
border:1px solid black;
|
||||
width:100px;
|
||||
margin:0;
|
||||
}
|
||||
ol{
|
||||
margin:0;
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<ol id="dynamic"></ol>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,59 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>List tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
function setUp() {
|
||||
var supportedTypes = ["decimal","decimal-leading-zero","upper-roman","lower-roman","lower-alpha","upper-alpha"];
|
||||
for (var i = 1;i<=100;i++){
|
||||
$('#dynamic').append($('<li />').text(i).css('list-style-type',supportedTypes[2]));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#dynamic{
|
||||
list-style-type:decimal;
|
||||
list-style-position: inside;
|
||||
font-size:20px;
|
||||
line-height:50px;
|
||||
|
||||
}
|
||||
|
||||
.small{
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.medium{
|
||||
font-size:18px;
|
||||
}
|
||||
.large{
|
||||
font-size:24px;
|
||||
}
|
||||
div{
|
||||
float:left;
|
||||
}
|
||||
h2 {
|
||||
clear:both;
|
||||
}
|
||||
li{
|
||||
border:1px solid black;
|
||||
width:100px;
|
||||
margin:0;
|
||||
}
|
||||
ol{
|
||||
margin:0;
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<ol id="dynamic"></ol>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,65 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Pseudoelement tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../test.js"></script>
|
||||
<style>
|
||||
.text *::before {
|
||||
content:" before!";
|
||||
}
|
||||
|
||||
.text *::after {
|
||||
content:" after!";
|
||||
}
|
||||
|
||||
.img *::before{
|
||||
content: url(../assets/image.jpg);
|
||||
}
|
||||
|
||||
.img *::after{
|
||||
content: url(../assets/image2.jpg);
|
||||
}
|
||||
|
||||
.background *::before{
|
||||
background: url(../assets/image_1.jpg);
|
||||
}
|
||||
|
||||
.background *::after{
|
||||
background: url(../assets/image2_1.jpg);
|
||||
}
|
||||
|
||||
.none *::before {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.none *::after {
|
||||
display:none;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="text">
|
||||
<span>Content 1</span>
|
||||
<span>Content 2</span>
|
||||
</div>
|
||||
|
||||
<div class="text none">
|
||||
<span>Content 1</span>
|
||||
<span>Content 2</span>
|
||||
</div>
|
||||
|
||||
<div class="text img">
|
||||
<span>Content 1</span>
|
||||
<span>Content 2</span>
|
||||
</div>
|
||||
|
||||
<div class="text background">
|
||||
<span>Content 1</span>
|
||||
<span>Content 2</span>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,41 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Chinese text</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<script>
|
||||
h2cOptions = {
|
||||
chinese: true
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.chn-text-block {
|
||||
width: 500px;
|
||||
font-family: serif;
|
||||
float: left;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="text" class="chn-text-block">
|
||||
<p> 注 释
|
||||
</p><p> 〔1〕 见本书第一卷《实践论》注〔6〕。
|
||||
</p><p> 〔2〕 见列宁《党的组织和党的出版物》。列宁在这篇论文中说:“这将是自由的写作,因为把一批又一批新生力量吸引到写作队伍中来的,不是私利贪欲,也不是名誉地位,而是社会主义思想和对劳动人民的同情。这将是自由的写作,因为它不是为饱食终日的贵妇人服务,不是为百无聊赖、胖得发愁的‘一万个上层分子’服务,而是为千千万万劳动人民,为这些国家的精华、国家的力量、国家的未来服务。这将是自由的写作,它要用社会主义无产阶级的经验和生气勃勃的工作去丰富人类革命思想的最新成就,它要使过去的经验(从原始空想的社会主义发展而成的科学社会主义)和现在的经验(工人同志们当前的斗争)之间经常发生相互作用。”(《列宁全集》第12卷,人民出版社1987年版,第96—97页)
|
||||
</p><p> 〔3〕 梁实秋(一九○三——一九八七),北京人。新月社主要成员。先后在复旦大学、北京大学等校任教。曾写过一些文艺评论,长时期致力于文学翻译工作和散文的写作。鲁迅对梁实秋的批评,见《三闲集·新月社批评家的任务》、《二心集·“硬译”与“文学的阶级性”》等文。(《鲁迅全集》第4卷,人民文学出版社1981年版,第159、195—212页)
|
||||
</p><p> 〔4〕 周作人(一八八五——一九六七),浙江绍兴人。曾在北京大学、燕京大学等校任教。五四运动时从事新文学写作。他的著述很多,有大量的散文集、文学专著和翻译作品。张资平(一八九三——一九五九),广东梅县人。他写过很多小说,曾在暨南大学、大夏大学兼任教职。周作人、张资平于一九三八年和一九三九年先后在北平、上海依附侵略中国的日本占领者。
|
||||
</p><p> 〔5〕 见鲁迅《二心集·对于左翼作家联盟的意见》(《鲁迅全集》第4卷,人民文学出版社1981年版,第237—238页)。
|
||||
</p><p> 〔6〕 参见鲁迅《且介亭杂文末编·附集·死》(《鲁迅全集》第6卷,人民文学出版社1981年版,第612页)。
|
||||
</p><p> 〔7〕 “小放牛”是中国一出传统的小歌舞剧。全剧只有两个角色,男角是牧童,女角是乡村小姑娘,以互相对唱的方式表现剧的内容。抗日战争初期,革命的文艺工作者利用这个歌舞剧的形式,变动其原来的词句,宣传抗日,一时颇为流行。
|
||||
</p><p> 〔8〕 “人、手、口、刀、牛、羊”是笔画比较简单的汉字,旧时一些小学国语读本把这几个字编在第一册的最初几课里。
|
||||
</p><p> 〔9〕 “阳春白雪”和“下里巴人”,都是公元前三世纪楚国的歌曲。“阳春白雪”是供少数人欣赏的较高级的歌曲;“下里巴人”是流传很广的民间歌曲。《文选·宋玉对楚王问》记载一个故事,说有人在楚都唱歌,唱“阳春白雪”时,“国中属而和者(跟着唱的),不过数十人”;但唱“下里巴人”时,“国中属而和者数千人”。
|
||||
</p><p> 〔10〕 见列宁《党的组织和党的出版物》。列宁在这篇论文中说:“写作事业应当成为整个无产阶级事业的一部分,成为由整个工人阶级的整个觉悟的先锋队所开动的一部巨大的社会民主主义机器的‘齿轮和螺丝钉’。”(《列宁全集》第12卷,人民出版社1987年版,第93页)
|
||||
</p><p> 〔11〕 亭子间是上海里弄房子中的一种小房间,位置在房子后部的楼梯中侧,狭小黑暗,因此租金比较低廉。解放以前,贫苦的作家、艺术家、知识分子和机关小职员,多半租这种房间居住。
|
||||
</p><p> 〔12〕 见本书第二卷《和中央社、扫荡报、新民报三记者的谈话》注〔3〕。
|
||||
</p><p> 〔13〕 法捷耶夫(一九○一——一九五六),苏联名作家。他所作的小说《毁灭》于一九二七年出版,内容是描写苏联国内战争时期由苏联远东滨海边区工人、农民和革命知识分子所组成的一支游击队同国内反革命白卫军以及日本武装干涉军进行斗争的故事。这部小说曾由鲁迅译为汉文。
|
||||
</p><p> 〔14〕 见鲁迅《集外集·自嘲》(《鲁迅全集》第7卷,人民文学出版社1981年版,第147页)。</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,49 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Text-decoration:line-through tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<script type="text/javascript">
|
||||
function setUp() {
|
||||
$('body').empty();
|
||||
$.each(['arial','verdana','tahoma','courier new'],function(i,e){
|
||||
var div = $('<div />').css('font-family',e).appendTo('body');
|
||||
for(var i=0;i<=10;i++){
|
||||
$('<div />').text('Testing texts').css('margin-top',1).css('border','1px solid black').css('font-size',(16+i*6)).appendTo(div);
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.small{
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.medium{
|
||||
font-size:18px;
|
||||
}
|
||||
.large{
|
||||
font-size:24px;
|
||||
}
|
||||
|
||||
div{
|
||||
text-decoration:line-through;
|
||||
|
||||
}
|
||||
|
||||
.lineheight{
|
||||
line-height:40px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
clear:both;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
Creating content through JavaScript
|
||||
</body>
|
||||
</html>
|
@ -1,21 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Text shadow tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style>
|
||||
span{
|
||||
text-shadow: 1px 1px 3px #888;
|
||||
}
|
||||
strong {
|
||||
text-shadow: 1px 1px 2px black, 0 0 1em blue, 0 0 0.2em blue;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
Some text <span> followed by text with shadow </span> followed by more text without shadow.
|
||||
<strong>Multi text shadow</strong> and some more text without shadow
|
||||
</body>
|
||||
</html>
|
@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Nested transform tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style>
|
||||
#first {
|
||||
background: indianred;
|
||||
margin-top: 100px;
|
||||
}
|
||||
#second {
|
||||
border: 10px solid red;
|
||||
background: darkseagreen;
|
||||
-webkit-transform: rotate(7.5deg); /* Chrome, Safari 3.1+ */
|
||||
-moz-transform: rotate(7.5deg); /* Firefox 3.5-15 */
|
||||
-ms-transform: rotate(7.5deg); /* IE 9 */
|
||||
-o-transform: rotate(7.5deg); /* Opera 10.50-12.00 */
|
||||
transform: rotate(7.5deg);
|
||||
}
|
||||
#third {
|
||||
background: cadetblue;
|
||||
-webkit-transform: rotate(-70.5deg); /* Chrome, Safari 3.1+ */
|
||||
-moz-transform: rotate(-70.5deg); /* Firefox 3.5-15 */
|
||||
-ms-transform: rotate(-70.5deg); /* IE 9 */
|
||||
-o-transform: rotate(-70.5deg); /* Opera 10.50-12.00 */
|
||||
transform: rotate(-70.5deg); /* Firefox 16+, IE 10+, Opera 12.10+ */
|
||||
|
||||
}
|
||||
div {
|
||||
display: inline-block;
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="first">First level content <div id="second">with second level content <div id="third">and third level content</div>, ending second</div>, ending first</div>
|
||||
</body>
|
||||
</html>
|
@ -1,81 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>z-index tests #1</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style>
|
||||
|
||||
div { font: 12px Arial; }
|
||||
|
||||
span.bold { font-weight: bold; }
|
||||
|
||||
#div1,#div3 {
|
||||
height: 80px;
|
||||
position: relative;
|
||||
border: 1px solid #669966;
|
||||
background-color: #ccffcc;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
#div2 {
|
||||
opacity: 0.8;
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
width: 150px;
|
||||
height: 200px;
|
||||
top: 20px;
|
||||
left: 170px;
|
||||
border: 1px solid #990000;
|
||||
background-color: #ffdddd;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#div4 {
|
||||
opacity: 0.8;
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 70px;
|
||||
top: 65px;
|
||||
left: 50px;
|
||||
border: 1px solid #000099;
|
||||
background-color: #ddddff;
|
||||
text-align: left;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<br />
|
||||
|
||||
No z-indexed content
|
||||
<div id="div1">
|
||||
<br /><span class="bold">DIV #1</span>
|
||||
<br />position: relative;
|
||||
<div id="div2">
|
||||
<br /><span class="bold">DIV #2</span>
|
||||
<br />position: absolute;
|
||||
<br />z-index: 1;
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div id="div3">
|
||||
<br /><span class="bold">DIV #3</span>
|
||||
<br />position: relative;
|
||||
<div id="div4">
|
||||
<br /><span class="bold">DIV #4</span>
|
||||
<br />position: absolute;
|
||||
<br />z-index: 2;
|
||||
</div>
|
||||
</div>
|
||||
Some more non-zindexed content
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,120 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context?redirectlocale=en-US&redirectslug=CSS%2FUnderstanding_z-index%2FThe_stacking_context
|
||||
-->
|
||||
<title>Understanding CSS z-index: The Stacking Context: Example Source</title>
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
* {
|
||||
margin: 0;
|
||||
}
|
||||
html {
|
||||
padding: 20px;
|
||||
font: 12px/20px Arial, sans-serif;
|
||||
}
|
||||
div {
|
||||
opacity: 0.7;
|
||||
position: relative;
|
||||
}
|
||||
h1 {
|
||||
font: inherit;
|
||||
font-weight: bold;
|
||||
}
|
||||
#div1, #div2 {
|
||||
border: 1px solid #696;
|
||||
padding: 10px;
|
||||
background-color: #cfc;
|
||||
}
|
||||
#div1 {
|
||||
z-index: 5;
|
||||
margin-bottom: 190px;
|
||||
}
|
||||
#div2 {
|
||||
z-index: 2;
|
||||
}
|
||||
#div3 {
|
||||
z-index: 4;
|
||||
opacity: 1;
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
left: 180px;
|
||||
width: 330px;
|
||||
border: 1px solid #900;
|
||||
background-color: #fdd;
|
||||
padding: 40px 20px 20px;
|
||||
}
|
||||
#div4, #div5 {
|
||||
border: 1px solid #996;
|
||||
background-color: #ffc;
|
||||
}
|
||||
#div4 {
|
||||
z-index: 6;
|
||||
margin-bottom: 15px;
|
||||
padding: 25px 10px 5px;
|
||||
}
|
||||
#div5 {
|
||||
z-index: 1;
|
||||
margin-top: 15px;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
#div6 {
|
||||
z-index: 3;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 180px;
|
||||
width: 150px;
|
||||
height: 125px;
|
||||
border: 1px solid #009;
|
||||
padding-top: 125px;
|
||||
background-color: #ddf;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="div1">
|
||||
<h1>Division Element #1</h1>
|
||||
<code>position: relative;<br/>
|
||||
z-index: 5;</code>
|
||||
</div>
|
||||
|
||||
<div id="div2">
|
||||
<h1>Division Element #2</h1>
|
||||
<code>position: relative;<br/>
|
||||
z-index: 2;</code>
|
||||
</div>
|
||||
|
||||
<div id="div3">
|
||||
|
||||
<div id="div4">
|
||||
<h1>Division Element #4</h1>
|
||||
<code>position: relative;<br/>
|
||||
z-index: 6;</code>
|
||||
</div>
|
||||
|
||||
<h1>Division Element #3</h1>
|
||||
<code>position: absolute;<br/>
|
||||
z-index: 4;</code>
|
||||
|
||||
<div id="div5">
|
||||
<h1>Division Element #5</h1>
|
||||
<code>position: relative;<br/>
|
||||
z-index: 1;</code>
|
||||
</div>
|
||||
|
||||
<div id="div6">
|
||||
<h1>Division Element #6</h1>
|
||||
<code>position: absolute;<br/>
|
||||
z-index: 3;</code>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,48 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>static position inside position relative</title>
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
html {
|
||||
padding: 20px;
|
||||
font: 12px/20px Arial, sans-serif;
|
||||
}
|
||||
#div1 {
|
||||
padding: 10px;
|
||||
background: #9bfff8;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#div2 {
|
||||
background: #7cb659;
|
||||
display: table;
|
||||
}
|
||||
|
||||
#div3 {
|
||||
float:left;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="div1">
|
||||
<h1>Div Element #1</h1>
|
||||
<code>position: relative;</code>
|
||||
<div id="div2">
|
||||
<h1>Div Element #2</h1>
|
||||
<code>position: static;</code>
|
||||
<div id="div3">
|
||||
<div>
|
||||
<h1>Div Element #3</h1>
|
||||
<code>float: left;</code>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,48 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Negative z-indexes</title>
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
html {
|
||||
padding: 20px;
|
||||
font: 12px/20px Arial, sans-serif;
|
||||
}
|
||||
#div1 {
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#div2 {
|
||||
background: #7cb659;
|
||||
position: absolute;
|
||||
z-index:-999998;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
#div3 {
|
||||
background: #b69f1a;
|
||||
position: absolute;
|
||||
z-index: -999999;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="div1">
|
||||
<div id="div2">
|
||||
<h1>Div Element #2</h1>
|
||||
<div id="div3">
|
||||
<div>
|
||||
<h1>Div Element #3</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,31 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>text above children with negative z-index; z-index tests #13</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
.outer {
|
||||
background-color:cyan;
|
||||
width:200px;
|
||||
height:200px;
|
||||
z-index:0;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.inner {
|
||||
background-color:green;
|
||||
width:100px;
|
||||
height:100px;
|
||||
z-index:-1;
|
||||
position:absolute;
|
||||
top:0;left:0;
|
||||
}
|
||||
</style></head>
|
||||
|
||||
<body>
|
||||
<div class="outer">outer
|
||||
<div class="inner"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,25 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>body text above children with negative index but body bgcolor below</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
* {margin:0;padding:0;}
|
||||
body {
|
||||
background-color: green;
|
||||
}
|
||||
#div1 {
|
||||
background-color:cyan;
|
||||
width:200px;
|
||||
height:200px;
|
||||
z-index:-1;
|
||||
position:absolute;
|
||||
top:0; left:0;
|
||||
}
|
||||
</style></head>
|
||||
|
||||
<body>body
|
||||
<div id="div1"></div>
|
||||
</body>
|
||||
</html>
|
@ -1,26 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>body text and bgcolor above children with negative z-index</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
* {margin:0;padding:0;}
|
||||
html {background-color: gray;}
|
||||
body {
|
||||
background-color: green;
|
||||
}
|
||||
#div1 {
|
||||
background-color:cyan;
|
||||
width:200px;
|
||||
height:200px;
|
||||
z-index:-1;
|
||||
position:absolute;
|
||||
top:0; left:0;
|
||||
}
|
||||
</style></head>
|
||||
|
||||
<body>body
|
||||
<div id="div1"></div>
|
||||
</body>
|
||||
</html>
|
@ -1,103 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>z-index tests #2</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
div { font: 12px Arial; }
|
||||
|
||||
span.bold { font-weight: bold; }
|
||||
|
||||
#div2 { z-index: 2; }
|
||||
#div3 { z-index: 1; }
|
||||
#div4 { z-index: 10; }
|
||||
|
||||
#div1,#div3 {
|
||||
height: 80px;
|
||||
position: relative;
|
||||
border: 1px solid #669966;
|
||||
background-color: #ccffcc;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
#div2 {
|
||||
opacity: 0.8;
|
||||
position: absolute;
|
||||
width: 150px;
|
||||
height: 200px;
|
||||
top: 20px;
|
||||
left: 170px;
|
||||
border: 1px solid #990000;
|
||||
background-color: #ffdddd;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#div4 {
|
||||
opacity: 0.8;
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 70px;
|
||||
top: 65px;
|
||||
left: 50px;
|
||||
border: 1px solid #000099;
|
||||
background-color: #ddddff;
|
||||
text-align: left;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
#div5{
|
||||
border: 1px solid #669966;
|
||||
background-color: #ccffcc;
|
||||
padding-left: 5px;
|
||||
position:relative;
|
||||
margin-bottom:-15px;
|
||||
height:50px;
|
||||
margin-top:10px;
|
||||
|
||||
}
|
||||
|
||||
#div6{
|
||||
border: 1px solid #000099;
|
||||
background-color: #ddddff;
|
||||
text-align: left;
|
||||
padding-left: 10px;
|
||||
|
||||
}
|
||||
|
||||
</style></head>
|
||||
|
||||
<body>
|
||||
|
||||
<br />
|
||||
|
||||
<div id="div1">
|
||||
<br /><span class="bold">DIV #1</span>
|
||||
<br />position: relative;
|
||||
<div id="div2">
|
||||
<br /><span class="bold">DIV #2</span>
|
||||
<br />position: absolute;
|
||||
<br />z-index: 2;
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div id="div3">
|
||||
<br /><span class="bold">DIV #3</span>
|
||||
<br />position: relative;
|
||||
<br />z-index: 1;
|
||||
<div id="div4">
|
||||
<br /><span class="bold">DIV #4</span>
|
||||
<br />position: absolute;
|
||||
<br />z-index: 10;
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="div5"><br />DIV #5<br />position:relative;<br /></div>
|
||||
|
||||
<div id ="div6"><br />DIV #6<br />position:static;<br /></div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,109 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>z-index tests #3</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
div { font: 12px Arial; }
|
||||
|
||||
span.bold { font-weight: bold; }
|
||||
|
||||
div.lev1 {
|
||||
width: 250px;
|
||||
height: 70px;
|
||||
position: relative;
|
||||
border: 2px solid #669966;
|
||||
background-color: #ccffcc;
|
||||
padding-left: 5px;
|
||||
|
||||
}
|
||||
|
||||
#container1 {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
left: 75px;
|
||||
}
|
||||
|
||||
div.lev2 {
|
||||
opacity: 0.9;
|
||||
width: 200px;
|
||||
height: 60px;
|
||||
position: relative;
|
||||
border: 2px solid #990000;
|
||||
background-color: #ffdddd;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
#container2 {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 110px;
|
||||
}
|
||||
|
||||
div.lev3 {
|
||||
z-index: 10;
|
||||
width: 100px;
|
||||
position: relative;
|
||||
border: 2px outset #000099;
|
||||
background-color: #ddddff;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
</style></head>
|
||||
|
||||
<body>
|
||||
|
||||
<br />
|
||||
|
||||
<div class="lev1">
|
||||
<span class="bold">LEVEL #1</span>
|
||||
|
||||
<div id="container1">
|
||||
|
||||
<div class="lev2">
|
||||
<br /><span class="bold">LEVEL #2</span>
|
||||
<br />z-index: 1;
|
||||
|
||||
<div id="container2">
|
||||
|
||||
<div class="lev3"><span class="bold">LEVEL #3</span></div>
|
||||
<div class="lev3"><span class="bold">LEVEL #3</span></div>
|
||||
<div class="lev3"><span class="bold">LEVEL #3</span></div>
|
||||
<div class="lev3"><span class="bold">LEVEL #3</span></div>
|
||||
<div class="lev3"><span class="bold">LEVEL #3</span></div>
|
||||
<div class="lev3"><span class="bold">LEVEL #3</span></div>
|
||||
<div class="lev3"><span class="bold">LEVEL #3</span></div>
|
||||
<div class="lev3"><span class="bold">LEVEL #3</span></div>
|
||||
<div class="lev3"><span class="bold">LEVEL #3</span></div>
|
||||
<div class="lev3"><span class="bold">LEVEL #3</span></div>
|
||||
<div class="lev3"><span class="bold">LEVEL #3</span></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="lev2">
|
||||
<br /><span class="bold">LEVEL #2</span>
|
||||
<br />z-index: 1;
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lev1" style="position:static">
|
||||
<span class="bold">LEVEL #1</span>
|
||||
</div>
|
||||
|
||||
<div class="lev1">
|
||||
<span class="bold">LEVEL #1</span>
|
||||
</div>
|
||||
|
||||
<div class="lev1">
|
||||
<span class="bold">LEVEL #1</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,35 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>z-index tests #4</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
div.lev1 {
|
||||
width: 250px;
|
||||
height: 70px;
|
||||
position: relative;
|
||||
border: 2px solid #669966;
|
||||
background-color: #ccffcc;
|
||||
padding-left: 5px;
|
||||
}
|
||||
div.background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 250px;
|
||||
background-color: #ffdddd;
|
||||
z-index: -1;
|
||||
}
|
||||
</style></head>
|
||||
|
||||
<body>
|
||||
<div class="lev1">
|
||||
<span>LEVEL #1</span>
|
||||
</div>
|
||||
<div class="background"></div>
|
||||
<div class="lev1">
|
||||
<span>LEVEL #1</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,34 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>z-index tests #5</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
div.lev1 {
|
||||
width: 250px;
|
||||
height: 70px;
|
||||
position: relative;
|
||||
border: 2px solid #669966;
|
||||
background-color: #ccffcc;
|
||||
padding-left: 5px;
|
||||
}
|
||||
div.background {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 250px;
|
||||
background-color: #ffdddd;
|
||||
}
|
||||
</style></head>
|
||||
|
||||
<body>
|
||||
<div class="lev1">
|
||||
LEVEL #1
|
||||
</div>
|
||||
<div class="background"></div>
|
||||
<div class="lev1">
|
||||
<span>LEVEL #1</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,33 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>z-index tests #6</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
div {
|
||||
width: 250px;
|
||||
height: 70px;
|
||||
position: relative;
|
||||
border: 2px solid #669966;
|
||||
background-color: #ccffcc;
|
||||
padding-left: 5px;
|
||||
}
|
||||
div.z0 {
|
||||
z-index: 0;
|
||||
top:105px;
|
||||
left:20px;
|
||||
background-color: #ffdddd;
|
||||
}
|
||||
|
||||
div.z1 {
|
||||
z-index: 1;
|
||||
}
|
||||
</style></head>
|
||||
|
||||
<body>
|
||||
<div class="z0"><span>z-index:0</span></div>
|
||||
<div>default z-index</div>
|
||||
<div class="z1">z-index:1</div>
|
||||
</body>
|
||||
</html>
|
@ -1,102 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Stacking without z-index</title>
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index?redirectlocale=en-US&redirectslug=CSS%2FUnderstanding_z-index%2FStacking_without_z-index -->
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
div {
|
||||
font: 12px Arial;
|
||||
}
|
||||
|
||||
span.bold { font-weight: bold; }
|
||||
|
||||
#normdiv {
|
||||
height: 70px;
|
||||
border: 1px solid #999966;
|
||||
background-color: #ffffcc;
|
||||
margin: 0px 50px 0px 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#reldiv1 {
|
||||
opacity: 0.7;
|
||||
height: 100px;
|
||||
position: relative;
|
||||
top: 30px;
|
||||
border: 1px solid #669966;
|
||||
background-color: #ccffcc;
|
||||
margin: 0px 50px 0px 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#reldiv2 {
|
||||
opacity: 0.7;
|
||||
height: 100px;
|
||||
position: relative;
|
||||
top: 15px;
|
||||
left: 20px;
|
||||
border: 1px solid #669966;
|
||||
background-color: #ccffcc;
|
||||
margin: 0px 50px 0px 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#absdiv1 {
|
||||
opacity: 0.7;
|
||||
position: absolute;
|
||||
width: 150px;
|
||||
height: 350px;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
border: 1px solid #990000;
|
||||
background-color: #ffdddd;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#absdiv2 {
|
||||
opacity: 0.7;
|
||||
position: absolute;
|
||||
width: 150px;
|
||||
height: 350px;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
border: 1px solid #990000;
|
||||
background-color: #ffdddd;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style></head>
|
||||
|
||||
<body>
|
||||
|
||||
<br /><br />
|
||||
|
||||
<div id="absdiv1">
|
||||
<br /><span class="bold">DIV #1</span>
|
||||
<br />position: absolute;
|
||||
</div>
|
||||
|
||||
<div id="reldiv1">
|
||||
<br /><span class="bold">DIV #2</span>
|
||||
<br />position: relative;
|
||||
</div>
|
||||
|
||||
<div id="reldiv2">
|
||||
<br /><span class="bold">DIV #3</span>
|
||||
<br />position: relative;
|
||||
</div>
|
||||
|
||||
<div id="absdiv2">
|
||||
<br /><span class="bold">DIV #4</span>
|
||||
<br />position: absolute;
|
||||
</div>
|
||||
|
||||
<div id="normdiv">
|
||||
<br /><span class="bold">DIV #5</span>
|
||||
<br />no positioning
|
||||
</div>
|
||||
|
||||
</body></html>
|
@ -1,104 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Stacking and float</title>
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/Stacking_and_float?redirectlocale=en-US&redirectslug=CSS%2FUnderstanding_z-index%2FStacking_and_float -->
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
div {
|
||||
font: 12px Arial;
|
||||
}
|
||||
|
||||
span.bold { font-weight: bold; }
|
||||
|
||||
#absdiv1 {
|
||||
opacity: 0.7;
|
||||
position: absolute;
|
||||
width: 150px;
|
||||
height: 200px;
|
||||
top: 10px;
|
||||
right: 140px;
|
||||
border: 1px solid #990000;
|
||||
background-color: #ffdddd;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#normdiv {
|
||||
/*opacity: 0.7;*/
|
||||
height: 100px;
|
||||
border: 1px solid #999966;
|
||||
background-color: #ffffcc;
|
||||
margin: 0px 10px 0px 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#flodiv1 {
|
||||
opacity: 0.7;
|
||||
margin: 0px 10px 0px 20px;
|
||||
float: left;
|
||||
width: 150px;
|
||||
height: 200px;
|
||||
border: 1px solid #009900;
|
||||
background-color: #ccffcc;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#flodiv2 {
|
||||
opacity: 0.7;
|
||||
margin: 0px 20px 0px 10px;
|
||||
float: right;
|
||||
width: 150px;
|
||||
height: 200px;
|
||||
border: 1px solid #009900;
|
||||
background-color: #ccffcc;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#absdiv2 {
|
||||
opacity: 0.7;
|
||||
position: absolute;
|
||||
width: 150px;
|
||||
height: 100px;
|
||||
top: 130px;
|
||||
left: 100px;
|
||||
border: 1px solid #990000;
|
||||
background-color: #ffdddd;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style></head>
|
||||
|
||||
<body>
|
||||
|
||||
<br /><br />
|
||||
|
||||
<div id="absdiv1">
|
||||
<br /><span class="bold">DIV #1</span>
|
||||
<br />position: absolute;
|
||||
</div>
|
||||
|
||||
<div id="flodiv1">
|
||||
<br /><span class="bold">DIV #2</span>
|
||||
<br />float: left;
|
||||
</div>
|
||||
|
||||
<div id="flodiv2">
|
||||
<br /><span class="bold">DIV #3</span>
|
||||
<br />float: right;
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div id="normdiv">
|
||||
<br /><span class="bold">DIV #4</span>
|
||||
<br />no positioning
|
||||
</div>
|
||||
|
||||
<div id="absdiv2">
|
||||
<br /><span class="bold">DIV #5</span>
|
||||
<br />position: absolute;
|
||||
</div>
|
||||
|
||||
</body></html>
|
@ -1,108 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head><title>Adding z-index</title>
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/Adding_z-index?redirectlocale=en-US&redirectslug=CSS%2FUnderstanding_z-index%2FAdding_z-index -->
|
||||
<script type="text/javascript" src="../../test.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
div {
|
||||
opacity: 0.7;
|
||||
font: 12px Arial;
|
||||
}
|
||||
|
||||
span.bold { font-weight: bold; }
|
||||
|
||||
#normdiv {
|
||||
z-index: 8;
|
||||
height: 70px;
|
||||
border: 1px solid #999966;
|
||||
background-color: #ffffcc;
|
||||
margin: 0px 50px 0px 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#reldiv1 {
|
||||
z-index: 3;
|
||||
height: 100px;
|
||||
position: relative;
|
||||
top: 30px;
|
||||
border: 1px solid #669966;
|
||||
background-color: #ccffcc;
|
||||
margin: 0px 50px 0px 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#reldiv2 {
|
||||
z-index: 2;
|
||||
height: 100px;
|
||||
position: relative;
|
||||
top: 15px;
|
||||
left: 20px;
|
||||
border: 1px solid #669966;
|
||||
background-color: #ccffcc;
|
||||
margin: 0px 50px 0px 50px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#absdiv1 {
|
||||
z-index: 5;
|
||||
position: absolute;
|
||||
width: 150px;
|
||||
height: 350px;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
border: 1px solid #990000;
|
||||
background-color: #ffdddd;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#absdiv2 {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
width: 150px;
|
||||
height: 350px;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
border: 1px solid #990000;
|
||||
background-color: #ffdddd;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style></head>
|
||||
|
||||
<body>
|
||||
|
||||
<br /><br />
|
||||
|
||||
<div id="absdiv1">
|
||||
<br /><span class="bold">DIV #1</span>
|
||||
<br />position: absolute;
|
||||
<br />z-index: 5;
|
||||
</div>
|
||||
|
||||
<div id="reldiv1">
|
||||
<br /><span class="bold">DIV #2</span>
|
||||
<br />position: relative;
|
||||
<br />z-index: 3;
|
||||
</div>
|
||||
|
||||
<div id="reldiv2">
|
||||
<br /><span class="bold">DIV #3</span>
|
||||
<br />position: relative;
|
||||
<br />z-index: 2;
|
||||
</div>
|
||||
|
||||
<div id="absdiv2">
|
||||
<br /><span class="bold">DIV #4</span>
|
||||
<br />position: absolute;
|
||||
<br />z-index: 1;
|
||||
</div>
|
||||
|
||||
<div id="normdiv">
|
||||
<br /><span class="bold">DIV #5</span>
|
||||
<br />no positioning
|
||||
<br />z-index: 8;
|
||||
</div>
|
||||
|
||||
</body></html>
|
@ -1,43 +0,0 @@
|
||||
U2FsdGVkX1/1OhTi++Zu8+GzAWDR9xD8SFu4sB/1mvbeKt7eF3z/t217AJii/H52
|
||||
FYMoPSnwFzEvXuiS/EIpVzRYugcfc4qSkOA2PE726V1b6UQoxbcJnHK4UW2464Yb
|
||||
a8dw+saN7KFpzaY0+L09QzIGqVMvtYQG2dTQk3dfAZ4Y/hduoGuCDReyRP7DbIJw
|
||||
WD933bja/p1HL91AnNo7lIGD529nXugBdlCAEeYGkeAfa7/Or+68sw7fhki3MQJw
|
||||
xWbo/oND/Fr4WzlGDeTQMTVfEVGYmT8K+aNtcKrgAp3SDQf37zuMnxVaKREmlXOF
|
||||
IRKaoR4jzDEgiwlsMZ7CvASwKDZDckFKjg3v/yKLjg+NKg2eET+VD+3CvTai5PHQ
|
||||
xRzPqkmyh+gh3Op2ZpTCtqnlgx7CfobAXjL4BOtu8aT6LZsoS/mMmqfbX49SDBw3
|
||||
wVXFuhPPGsXDJD2F39kG5vX6LeygOGPMOPbzqimUftWlxcUJhb4mGKV5qcLz+WzH
|
||||
17E2fv6kEwMRTfjGjUR9zMR8JjBBu0GcKGyiW6MqQwjF+BXvWoIRuwv99x2cpOjN
|
||||
fAHk9Y9IgJlzWmrTpg1i5sqTNKgmQaKqarJqXwvuq86kJuCMkYr0SxleUlAmbzpC
|
||||
w25JAMcNqabQLDaTJfV6V5EWAh3sHh+lAcL+QKs2Ddx5K9RwwCnNXtIhatECsu0n
|
||||
oNDeWcFtaLmGVF/zXpkCkKBg0EsEcFIXZM662TaGCqukIktq61/UsuR7hVQdPXyH
|
||||
/4rJTITQAXbi+FaQXzrrxKrikU7Rdovn6az5YNXBXh0pMQ9FrahxhYhDrpzpCsNc
|
||||
STL2JN50u3X28ZgfRs7rB5fY9Xr5pERIAFSrNzFPCHzlStoYNSphJP8lO/XjNkcn
|
||||
CTOzZrzxVpzqqzXlmArCfx3QtVo+WUUUW9hdOBgKLl19Wt0x5ZvYDPm6ODht9BjD
|
||||
wfbmkRvdP9CTICBR17l2tPiGcu+4paTKBF6W6aSxQU7Z48uZP19/4cuOiITbcYnt
|
||||
4wHoNk+M5G9SjLSsOlfmYNMcl0D57AOcbyUUTMZ2Wu0zc3/StJ9aotzEcFSxA1Gs
|
||||
wPZr/2iqeEynJmUQeFjs01JSwxwYlLF+HOStdn6MEbsW4ftxsXO9Mr2NGAOTaO1/
|
||||
Y8pyMCRJKOH6kRvHPpzza/stIZQQZk+PMRzS3PgMXsnJoF7cuanrWXJTgiNT6B37
|
||||
y/ARNr3KtZTGOjc5gE+k32hPuqPi5tVKPrFVUrG2l/87Gqjs4JqNDTjTHBlUIViT
|
||||
y87uB2f8/8/V50lXf+RYGPKaJ+jzbyaUxp6QRZdqJk8CEZQnrGwpUEzBVMREd+Ow
|
||||
jn99f/Isn5Vadsdmt/aMy7+TnLVyjPqucIo8dUdkWdfLKF1Q7M06rYgu9MCrsbgi
|
||||
hGp1/YjqSmYxWZuSUZHvd4ps2x9YI6wuwdWXAH/7+L0IVUghpSNoARrsmi/D7Rg5
|
||||
4zF6eCOqH13z1luMRg1ZMpRyVQcI/Yu3IbyepnuIeYIqPklDJ6jl3kIdubEtXZTV
|
||||
1XMlTvZjFuRKLeUXsF/ecTmlob+rc06YvOu91vwpxSMkpYUIc/Yt4tTWey1AbmTG
|
||||
t4pf8q0cVXrVRuXf8HFEEqQlXumJGWi/WCxAawj35znEIquQDu9ERLgSemdTFH2z
|
||||
ncoJseApHD9Gf2UpM4Vva+XdI9wrlYURr83/gOxenCgMq7wCWH87yuCG1IsOryPx
|
||||
1DbES6axy6P+XBQJTDHK560zKSNF+3VVBGEeTQRMAnQs/IHlwWu7Af0DTmUAEO2Z
|
||||
S1R+Ex2HWMM3i8/Sr8P1JDkm0u7gn2wkfI0xEIf5B10md1iniKb0GovMlfMGJTTo
|
||||
+mytGTp3XUZl8lXDpbLTR9nqfpB+hL5Qi30Dv08CAQdvX9OzOEQz5T//t13wAKlo
|
||||
bsbzwIuLhyYbua+wz/3uMS6QAbNNVCgIm/J1rqlwLRmzvSTJyhraamjd2UuwwIau
|
||||
fgdIA5bYqdagzbUuIk8msItfUrAbhxkyBElVb5RgLVJsUbBQTHW3anrbsTxxMrcR
|
||||
9jnZZV2Is2ahbnmcqqIjr7fxSqTCtwpyBxRkW8Bh+Sfu2R8x+DLcJ+ID25fbxWto
|
||||
QrDSGEifpW/5bjGx4lM0j8IxoWqOl0600hlzGsD5ynSu5WPpXQ0CMvuuLXOR4CbZ
|
||||
kzE5kQXAeQzfwwPcWMMhwt5F4hXAXY/+jM0TfuSc7Z9PYYRWdoDg3awRNlQJS5rk
|
||||
wDwbMHKUcdi4XSwIhEdbZ4zBo0o7xXKn2XSBNy+Ym39pKWMwOrffsPtWDV+qTHpD
|
||||
P5rhXEW8aD01kMkxjO2pRZ7nEDQ7VGpi3MuW9FAjXZjcc1grnZSxbKz437K9obI7
|
||||
zHXGcodAXjU4Oxhs/m8JHVaHsDG5LNxLSmArsmbwcu65mlBCXcefcwOUNoVQDmZG
|
||||
ENSAMlVAUX7RJ9nxXI9AqKKuVAYSMznseY3V22BCDrRR0nbVkAWjuBTKU6ajfjQ6
|
||||
W2uhAzl8kH+9Xi10jt5Fhn93b8z4VjrcpZmW/gJuEHm8FY2UFF0P1y3YMCDqCPaz
|
||||
gXsFZVKPPIswg/xBHB9GhiCSHnvivu/K8Ni4FcBW7smBHuqkk0VoN7CdZvNF0CuX
|
||||
EANCwDD53hSmfyxR/SY6y1PQCEsX5AiRS8rMGV2bqOjP6/oM9+2JmkRZ3I6Jht2f
|
||||
sxJsRUTyjecCcwnGDgmLDCZDJqLJoOE6zlRuAOvY1U7m2cFrf9EouOlYUXSeBaEh
|
23
tests/external-content.html
Normal file
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>External content tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link href="#" type="text/css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript" src="../external/jquery-1.6.2.js"></script>
|
||||
<script type="text/javascript" src="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
$('body').html2canvas();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1>Iframe</h1>
|
||||
<iframe src="http://www.google.com" style="width:400px;height:300px;border:5px solid black;"></iframe>
|
||||
</body>
|
||||
</html>
|
@ -1,15 +1,29 @@
|
||||
<!--
|
||||
* @author Niklas von Hertzen <niklas at hertzen.com>
|
||||
* @created 16.7.2011
|
||||
* @website http://hertzen.com
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Form tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../test.js"></script>
|
||||
<link href="#" type="text/css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript" src="../external/jquery-1.6.2.min.js"></script>
|
||||
<script type="text/javascript" src="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
$('body').html2canvas();
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<body>
|
||||
<input type="text" value="textbox" />
|
||||
<input type="text" value="textbox" style="border:5px solid navy;" />
|
||||
<input type="text" value="textbox" style="border:5px solid navy;height:40px;" />
|
||||
@ -46,12 +60,12 @@
|
||||
<input type="submit" value="Submit" style="width:200px;" />
|
||||
<input type="Button" value="Button" style="width:200px;height:50px;" />
|
||||
<input type="Reset" value="Reset" style="width:200px;height:50px;text-align:left;" />
|
||||
|
||||
|
||||
<hr />
|
||||
|
||||
|
||||
<textarea> </textarea>
|
||||
<textarea style="border-width:10px;"></textarea>
|
||||
|
||||
|
||||
<textarea> text </textarea>
|
||||
<textarea style="border-width:10px;">text</textarea>
|
||||
</body>
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
57
tests/images.html
Normal file
@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Image tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link href="#" type="text/css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript" src="../external/jquery-1.6.2.min.js"></script>
|
||||
<script type="text/javascript" src="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
$('body').html2canvas();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.small{
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.medium{
|
||||
font-size:18px;
|
||||
}
|
||||
.large{
|
||||
font-size:24px;
|
||||
}
|
||||
div{
|
||||
float:left;
|
||||
}
|
||||
h2 {
|
||||
clear:both;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<img src="image.jpg" />
|
||||
<img src="image.jpg" style="width:50px;height:400px;" />
|
||||
<img src="image.jpg" style="width:500px;" />
|
||||
<img src="image.jpg" style="width:500px;height:40px;" />
|
||||
|
||||
|
||||
<img src="image.jpg" style="padding:20px;border:5px solid black;" />
|
||||
|
||||
<img src="image.jpg" style="padding-bottom:20px;border-top:5px solid black;clear:both;" />
|
||||
|
||||
|
||||
<img src="image.jpg" style="padding-top:20px;border-top:5px solid black;clear:both;width:50px;" />
|
||||
<img src="image.jpg" style="padding-top:20px;border-top:5px solid black;clear:both;width:50px;height:25px;" />
|
||||
|
||||
<img src="image.jpg" style="width:0px;height:0px;border:1px solid black" />
|
||||
<img src="image.jpg" style="width:0px;height:0px;" />
|
||||
|
||||
</body>
|
||||
</html>
|
87
tests/lists.html
Normal file
@ -0,0 +1,87 @@
|
||||
<!--
|
||||
* @author Niklas von Hertzen <niklas at hertzen.com>
|
||||
* @created 16.7.2011
|
||||
* @website http://hertzen.com
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>List tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
|
||||
|
||||
<script type="text/javascript" src="../external/jquery-1.6.2.min.js"></script>
|
||||
<script type="text/javascript" src="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
var supportedTypes = ["decimal","decimal-leading-zero","upper-roman","lower-roman","lower-alpha","upper-alpha"];
|
||||
for (var i = 1;i<=100;i++){
|
||||
|
||||
$('#dynamic').append($('<li />').text(i).css('list-style-type',supportedTypes[Math.round(Math.random()*supportedTypes.length)]));
|
||||
}
|
||||
|
||||
|
||||
$('body').html2canvas();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#dynamic{
|
||||
list-style-type:decimal;
|
||||
list-style-position: inside;
|
||||
font-size:20px;
|
||||
line-height:50px;
|
||||
|
||||
}
|
||||
|
||||
.small{
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.medium{
|
||||
font-size:18px;
|
||||
}
|
||||
.large{
|
||||
font-size:24px;
|
||||
}
|
||||
div{
|
||||
float:left;
|
||||
}
|
||||
h2 {
|
||||
clear:both;
|
||||
}
|
||||
li{
|
||||
border:1px solid black;
|
||||
width:100px;
|
||||
margin:0;
|
||||
}
|
||||
ol{
|
||||
margin:0;
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<ul>
|
||||
<li>First</li>
|
||||
<li style="list-style-position:inside; ">Second</li>
|
||||
<li>Third</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<ol>
|
||||
<li>First</li>
|
||||
<li style="list-style-position:inside; ">Second<br />new line</li>
|
||||
<li style="list-style-position:inside; "></li>
|
||||
<li style="list-style-position:outside;">Third</li>
|
||||
|
||||
</ol>
|
||||
|
||||
<ol id="dynamic">
|
||||
|
||||
</ol>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -3,7 +3,17 @@
|
||||
<head>
|
||||
<title>Overflow tests</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="../test.js"></script>
|
||||
<link href="#" type="text/css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript" src="../external/jquery-1.6.2.min.js"></script>
|
||||
<script type="text/javascript" src="../build/html2canvas.js"></script>
|
||||
<script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(window).ready(function() {
|
||||
$('body').html2canvas({letterRendering:true});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.small{
|
||||
font-size:14px;
|
||||
@ -28,22 +38,23 @@
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<body>
|
||||
<h1>Overflow: visible</h1>
|
||||
<div> Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like <b>Aldus PageMaker</b> including versions of Lorem Ipsum.
|
||||
<div>
|
||||
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like <b>Aldus PageMaker</b> including versions of Lorem Ipsum.
|
||||
</div>
|
||||
|
||||
<h1>Overflow: hidden</h1>
|
||||
<div style="overflow:hidden;">
|
||||
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s
|
||||
|
||||
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s
|
||||
|
||||
with the release of <div style="border-width:10px 0 5px 0;background:green;">a</div>Letraset sheets containing Lorem Ipsum passages, <img src="image.jpg" /> and more recently with desktop publishing software like <b>Aldus PageMaker</b> including versions of Lorem Ipsum.
|
||||
|
||||
|
||||
|
||||
|
||||
<div style="overflow:visible;position:relative;"><u>position:relative within a overflow:hidden element</u><br /> <br />
|
||||
|
||||
|
||||
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like <b>Aldus PageMaker</b> including versions of Lorem Ipsum.
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|