html2canvas/src/Renderer.js
2013-12-23 15:27:46 +02:00

112 lines
3.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

_html2canvas.Renderer = function(parseQueue, options){
function sortZindex(a, b) {
if (a === 'children') {
return -1;
} else if (b === 'children') {
return 1;
} else {
return a - b;
}
}
// 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) {
contextForChildren = stub.context = {
children: [{node:node, children: []}]
};
childrenDest = undefined;
} else if (isPositioned || isFloated) {
childrenDest = stub.children = [];
}
if (zi === 0 && specialParent) {
specialParent.push(stub);
} else {
if (!context[zi]) { context[zi] = []; }
context[zi].push(stub);
}
node.zIndex.children.forEach(function(childNode) {
insert(contextForChildren, childNode, childrenDest);
});
}
insert(rootContext, rootNode);
return rootContext;
})(parseQueue);
function sortZ(context) {
Object.keys(context).sort(sortZindex).forEach(function(zi) {
var nonPositioned = [],
floated = [],
positioned = [],
list = [];
// 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);
}
});
});
}
sortZ(rootContext);
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 !== "function" ) {
throw new Error("Invalid renderer defined");
}
return renderer;
}
return getRenderer(options.renderer)(parseQueue, options, document, createRenderQueue(parseQueue.stack), _html2canvas);
};