mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
refactoring
This commit is contained in:
parent
c3e9636e4f
commit
c72a02bf64
358
src/Core.js
358
src/Core.js
@ -7,216 +7,196 @@ html2canvas;
|
||||
|
||||
|
||||
function h2clog(a) {
|
||||
if (_html2canvas.logging && window.console && window.console.log) {
|
||||
window.console.log(a);
|
||||
}
|
||||
if (_html2canvas.logging && window.console && window.console.log) {
|
||||
window.console.log(a);
|
||||
}
|
||||
}
|
||||
|
||||
_html2canvas.Util = {};
|
||||
|
||||
_html2canvas.Util.backgroundImage = function (src) {
|
||||
|
||||
if (/data:image\/.*;base64,/i.test( src ) || /^(-webkit|-moz|linear-gradient|-o-)/.test( src )) {
|
||||
return src;
|
||||
}
|
||||
|
||||
if (src.toLowerCase().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 );
|
||||
}
|
||||
|
||||
if (/data:image\/.*;base64,/i.test( src ) || /^(-webkit|-moz|linear-gradient|-o-)/.test( src )) {
|
||||
return src;
|
||||
}
|
||||
|
||||
if (src.toLowerCase().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;
|
||||
};
|
||||
|
||||
_html2canvas.Util.Bounds = function getBounds (el) {
|
||||
var clientRect,
|
||||
bounds = {};
|
||||
var clientRect,
|
||||
bounds = {};
|
||||
|
||||
if (el.getBoundingClientRect){
|
||||
clientRect = el.getBoundingClientRect();
|
||||
if (el.getBoundingClientRect){
|
||||
clientRect = el.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;
|
||||
// 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;
|
||||
|
||||
// older IE doesn't have width/height, but top/bottom instead
|
||||
bounds.width = clientRect.width || (clientRect.right - clientRect.left);
|
||||
bounds.height = clientRect.height || (clientRect.bottom - clientRect.top);
|
||||
// older IE doesn't have width/height, but top/bottom instead
|
||||
bounds.width = clientRect.width || (clientRect.right - clientRect.left);
|
||||
bounds.height = clientRect.height || (clientRect.bottom - clientRect.top);
|
||||
|
||||
return bounds;
|
||||
return bounds;
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_html2canvas.Util.getCSS = function (el, attribute) {
|
||||
// return $(el).css(attribute);
|
||||
// return $(el).css(attribute);
|
||||
|
||||
var val;
|
||||
var val;
|
||||
|
||||
function toPX( attribute, val ) {
|
||||
var rsLeft = el.runtimeStyle && el.runtimeStyle[ attribute ],
|
||||
left,
|
||||
style = el.style;
|
||||
function toPX( attribute, val ) {
|
||||
var rsLeft = el.runtimeStyle && el.runtimeStyle[ attribute ],
|
||||
left,
|
||||
style = el.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
|
||||
// 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 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( val ) && /^-?\d/.test( val ) ) {
|
||||
if ( !/^-?[0-9]+\.?[0-9]*(?:px)?$/i.test( val ) && /^-?\d/.test( val ) ) {
|
||||
|
||||
// Remember the original values
|
||||
left = style.left;
|
||||
// Remember the original values
|
||||
left = style.left;
|
||||
|
||||
// Put in the new values to get a computed value out
|
||||
if ( rsLeft ) {
|
||||
el.runtimeStyle.left = el.currentStyle.left;
|
||||
}
|
||||
style.left = attribute === "fontSize" ? "1em" : (val || 0);
|
||||
val = style.pixelLeft + "px";
|
||||
// Put in the new values to get a computed value out
|
||||
if ( rsLeft ) {
|
||||
el.runtimeStyle.left = el.currentStyle.left;
|
||||
}
|
||||
style.left = attribute === "fontSize" ? "1em" : (val || 0);
|
||||
val = style.pixelLeft + "px";
|
||||
|
||||
// Revert the changed values
|
||||
style.left = left;
|
||||
if ( rsLeft ) {
|
||||
el.runtimeStyle.left = rsLeft;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!/^(thin|medium|thick)$/i.test( val )) {
|
||||
return Math.round(parseFloat( val )) + "px";
|
||||
}
|
||||
|
||||
return val;
|
||||
// Revert the changed values
|
||||
style.left = left;
|
||||
if ( rsLeft ) {
|
||||
el.runtimeStyle.left = rsLeft;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ( window.getComputedStyle ) {
|
||||
if ( previousElement !== el ) {
|
||||
computedCSS = document.defaultView.getComputedStyle(el, null);
|
||||
}
|
||||
val = computedCSS[ attribute ];
|
||||
|
||||
if ( attribute === "backgroundPosition" ) {
|
||||
|
||||
val = (val.split(",")[0] || "0 0").split(" ");
|
||||
|
||||
val[ 0 ] = ( val[0].indexOf( "%" ) === -1 ) ? toPX( attribute + "X", val[ 0 ] ) : val[ 0 ];
|
||||
val[ 1 ] = ( val[1] === undefined ) ? val[0] : val[1]; // IE 9 doesn't return double digit always
|
||||
val[ 1 ] = ( val[1].indexOf( "%" ) === -1 ) ? toPX( attribute + "Y", val[ 1 ] ) : val[ 1 ];
|
||||
} else if ( /border(Top|Bottom)(Left|Right)Radius/.test( attribute) ) {
|
||||
var arr = val.split(" ");
|
||||
if ( arr.length <= 1 ) {
|
||||
arr[ 1 ] = arr[ 0 ];
|
||||
}
|
||||
arr[ 0 ] = parseInt( arr[ 0 ], 10 );
|
||||
arr[ 1 ] = parseInt( arr[ 1 ], 10 );
|
||||
val = arr;
|
||||
}
|
||||
|
||||
} else if ( el.currentStyle ) {
|
||||
// IE 9>
|
||||
if (attribute === "backgroundPosition") {
|
||||
// Older IE uses -x and -y
|
||||
val = [ toPX( attribute + "X", el.currentStyle[ attribute + "X" ] ), toPX( attribute + "Y", el.currentStyle[ attribute + "Y" ] ) ];
|
||||
} else {
|
||||
|
||||
val = toPX( attribute, el.currentStyle[ attribute ] );
|
||||
|
||||
if (/^(border)/i.test( attribute ) && /^(medium|thin|thick)$/i.test( val )) {
|
||||
switch (val) {
|
||||
case "thin":
|
||||
val = "1px";
|
||||
break;
|
||||
case "medium":
|
||||
val = "0px"; // this is wrong, it should be 3px but IE uses medium for no border as well.. TODO find a work around
|
||||
break;
|
||||
case "thick":
|
||||
val = "5px";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!/^(thin|medium|thick)$/i.test( val )) {
|
||||
return Math.round(parseFloat( val )) + "px";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return val;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//return $(el).css(attribute);
|
||||
if ( window.getComputedStyle ) {
|
||||
if ( previousElement !== el ) {
|
||||
computedCSS = document.defaultView.getComputedStyle(el, null);
|
||||
}
|
||||
val = computedCSS[ attribute ];
|
||||
|
||||
if ( attribute === "backgroundPosition" ) {
|
||||
|
||||
val = (val.split(",")[0] || "0 0").split(" ");
|
||||
|
||||
val[ 0 ] = ( val[0].indexOf( "%" ) === -1 ) ? toPX( attribute + "X", val[ 0 ] ) : val[ 0 ];
|
||||
val[ 1 ] = ( val[1] === undefined ) ? val[0] : val[1]; // IE 9 doesn't return double digit always
|
||||
val[ 1 ] = ( val[1].indexOf( "%" ) === -1 ) ? toPX( attribute + "Y", val[ 1 ] ) : val[ 1 ];
|
||||
} else if ( /border(Top|Bottom)(Left|Right)Radius/.test( attribute) ) {
|
||||
var arr = val.split(" ");
|
||||
if ( arr.length <= 1 ) {
|
||||
arr[ 1 ] = arr[ 0 ];
|
||||
}
|
||||
arr[ 0 ] = parseInt( arr[ 0 ], 10 );
|
||||
arr[ 1 ] = parseInt( arr[ 1 ], 10 );
|
||||
val = arr;
|
||||
}
|
||||
|
||||
} else if ( el.currentStyle ) {
|
||||
// IE 9>
|
||||
if (attribute === "backgroundPosition") {
|
||||
// Older IE uses -x and -y
|
||||
val = [ toPX( attribute + "X", el.currentStyle[ attribute + "X" ] ), toPX( attribute + "Y", el.currentStyle[ attribute + "Y" ] ) ];
|
||||
} else {
|
||||
|
||||
val = toPX( attribute, el.currentStyle[ attribute ] );
|
||||
|
||||
if (/^(border)/i.test( attribute ) && /^(medium|thin|thick)$/i.test( val )) {
|
||||
switch (val) {
|
||||
case "thin":
|
||||
val = "1px";
|
||||
break;
|
||||
case "medium":
|
||||
val = "0px"; // this is wrong, it should be 3px but IE uses medium for no border as well.. TODO find a work around
|
||||
break;
|
||||
case "thick":
|
||||
val = "5px";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
};
|
||||
|
||||
|
||||
_html2canvas.Util.BackgroundPosition = function ( el, bounds, image ) {
|
||||
// TODO add support for multi image backgrounds
|
||||
// TODO add support for multi image backgrounds
|
||||
|
||||
var bgposition = _html2canvas.Util.getCSS( el, "backgroundPosition" ) ,
|
||||
topPos,
|
||||
left,
|
||||
percentage,
|
||||
val;
|
||||
var bgposition = _html2canvas.Util.getCSS( el, "backgroundPosition" ) ,
|
||||
topPos,
|
||||
left,
|
||||
percentage,
|
||||
val;
|
||||
|
||||
if (bgposition.length === 1){
|
||||
val = bgposition;
|
||||
if (bgposition.length === 1){
|
||||
val = bgposition;
|
||||
|
||||
bgposition = [];
|
||||
bgposition = [];
|
||||
|
||||
bgposition[0] = val;
|
||||
bgposition[1] = val;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return {
|
||||
top: topPos,
|
||||
left: left
|
||||
};
|
||||
|
||||
return {
|
||||
top: topPos,
|
||||
left: left
|
||||
};
|
||||
};
|
||||
|
||||
_html2canvas.Util.Extend = function (options, defaults) {
|
||||
for (var key in options) {
|
||||
if (options.hasOwnProperty(key)) {
|
||||
defaults[key] = options[key];
|
||||
}
|
||||
for (var key in options) {
|
||||
if (options.hasOwnProperty(key)) {
|
||||
defaults[key] = options[key];
|
||||
}
|
||||
return defaults;
|
||||
}
|
||||
return defaults;
|
||||
};
|
||||
|
||||
|
||||
@ -229,43 +209,43 @@ _html2canvas.Util.Extend = function (options, defaults) {
|
||||
_html2canvas.Util.Children = function( elem ) {
|
||||
|
||||
|
||||
var children;
|
||||
try {
|
||||
var children;
|
||||
try {
|
||||
|
||||
children = (elem.nodeName && elem.nodeName.toUpperCase() === "IFRAME") ?
|
||||
elem.contentDocument || elem.contentWindow.document : (function( array ){
|
||||
var ret = [];
|
||||
children = (elem.nodeName && elem.nodeName.toUpperCase() === "IFRAME") ?
|
||||
elem.contentDocument || elem.contentWindow.document : (function( array ){
|
||||
var ret = [];
|
||||
|
||||
if ( array !== null ) {
|
||||
if ( array !== null ) {
|
||||
|
||||
(function( first, second ) {
|
||||
var i = first.length,
|
||||
j = 0;
|
||||
|
||||
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++ ];
|
||||
}
|
||||
}
|
||||
|
||||
first.length = i;
|
||||
|
||||
return first;
|
||||
})( ret, array );
|
||||
(function( first, second ) {
|
||||
var i = first.length,
|
||||
j = 0;
|
||||
|
||||
if ( typeof second.length === "number" ) {
|
||||
for ( var l = second.length; j < l; j++ ) {
|
||||
first[ i++ ] = second[ j ];
|
||||
}
|
||||
|
||||
return ret;
|
||||
})( elem.childNodes );
|
||||
} else {
|
||||
while ( second[j] !== undefined ) {
|
||||
first[ i++ ] = second[ j++ ];
|
||||
}
|
||||
}
|
||||
|
||||
} catch (ex) {
|
||||
h2clog("html2canvas.Util.Children failed with exception: " + ex.message);
|
||||
children = [];
|
||||
}
|
||||
return children;
|
||||
first.length = i;
|
||||
|
||||
return first;
|
||||
})( ret, array );
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
})( elem.childNodes );
|
||||
|
||||
} catch (ex) {
|
||||
h2clog("html2canvas.Util.Children failed with exception: " + ex.message);
|
||||
children = [];
|
||||
}
|
||||
return children;
|
||||
};
|
||||
|
104
src/Renderer.js
104
src/Renderer.js
@ -1,66 +1,58 @@
|
||||
_html2canvas.Renderer = function(parseQueue, options){
|
||||
var queue = [], renderer;
|
||||
|
||||
function sortZ(zStack){
|
||||
var subStacks = [],
|
||||
stackValues = [],
|
||||
zStackChildren = zStack.children,
|
||||
s,
|
||||
i,
|
||||
stackLen,
|
||||
zValue,
|
||||
zLen,
|
||||
stackChild,
|
||||
b,
|
||||
subStackLen;
|
||||
function createRenderQueue(parseQueue) {
|
||||
var queue = [];
|
||||
|
||||
var sortZ = function(zStack){
|
||||
var subStacks = [],
|
||||
stackValues = [];
|
||||
|
||||
for (s = 0, zLen = zStackChildren.length; s < zLen; s+=1){
|
||||
|
||||
stackChild = zStackChildren[s];
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
for (i = 0, stackLen = stackValues.length; i < stackLen; i+=1){
|
||||
zValue = stackValues[i];
|
||||
for (b = 0, subStackLen = subStacks.length; b <= subStackLen; b+=1){
|
||||
|
||||
if (subStacks[b].zindex === zValue){
|
||||
stackChild = subStacks.splice(b, 1);
|
||||
sortZ(stackChild[0]);
|
||||
break;
|
||||
|
||||
zStack.children.forEach(function(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;
|
||||
});
|
||||
|
||||
stackValues.forEach(function(zValue) {
|
||||
var index;
|
||||
|
||||
subStacks.some(function(stack, i){
|
||||
index = i;
|
||||
return (stack.zindex === zValue);
|
||||
});
|
||||
sortZ(subStacks.splice(index, 1)[0]);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
sortZ(parseQueue.zIndex);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
if ( typeof renderer._create !== "function" ) {
|
||||
throw new Error("Invalid renderer defined");
|
||||
}
|
||||
return renderer;
|
||||
}
|
||||
|
||||
sortZ(parseQueue.zIndex);
|
||||
|
||||
if (typeof options.renderer === "string" && _html2canvas.Renderer[options.renderer] !== undefined) {
|
||||
renderer = _html2canvas.Renderer[options.renderer](options);
|
||||
} else if (typeof options.renderer === "function") {
|
||||
renderer = options.renderer(options);
|
||||
} else {
|
||||
throw new Error("Unknown renderer");
|
||||
}
|
||||
|
||||
if ( typeof renderer._create !== "function" ) {
|
||||
throw new Error("Invalid renderer defined");
|
||||
}
|
||||
|
||||
return renderer._create( parseQueue, options, document, queue, _html2canvas );
|
||||
|
||||
return getRenderer(options.renderer)._create(parseQueue, options, document, createRenderQueue(parseQueue), _html2canvas);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user