Use Color objects for colors

This commit is contained in:
MoyuScript 2014-12-13 18:10:41 +02:00
parent 068151cc91
commit 15dd95c15c
11 changed files with 198 additions and 147 deletions

View File

@ -14,6 +14,6 @@
"globals": {
"jQuery": true
},
"predef": ["NodeParser", "NodeContainer", "StackingContext", "TextContainer", "PseudoElementContainer", "ImageLoader", "CanvasRenderer", "Renderer", "Support", "bind", "Promise", "getBounds", "offsetBounds", "XHR",
"predef": ["NodeParser", "NodeContainer", "Color", "StackingContext", "TextContainer", "PseudoElementContainer", "ImageLoader", "CanvasRenderer", "Renderer", "Support", "bind", "Promise", "getBounds", "offsetBounds", "XHR",
"ImageContainer", "ProxyImageContainer", "DummyImageContainer", "Font", "FontMetrics", "GradientContainer", "LinearGradientContainer", "WebkitGradientContainer", "SVGContainer", "SVGNodeContainer", "FrameContainer", "html2canvas", "log", "smallImage", "parseBackgrounds", "loadUrlDocument", "decode64", "Proxy", "ProxyURL"]
}

153
dist/html2canvas.js vendored
View File

@ -833,6 +833,10 @@ function Color(value) {
this.hex3(value);
}
Color.prototype.isTransparent = function() {
return this.a === 0;
};
var _hex3 = /^#([a-f0-9]{3})$/i;
Color.prototype.hex3 = function(value) {
@ -883,6 +887,11 @@ Color.prototype.rgba = function(value) {
return match !== null;
};
Color.prototype.toString = function() {
return this.a !== null ?
"rgba(" + [this.r, this.g, this.b, this.a].join(",") + ")" :
"rgb(" + [this.r, this.g, this.b].join(",") + ")";
};
Color.prototype.namedColor = function(value) {
var color = colors[value.toLowerCase()];
@ -890,6 +899,9 @@ Color.prototype.namedColor = function(value) {
this.r = color[0];
this.g = color[1];
this.b = color[2];
} else if (value.toLowerCase() === "transparent") {
this.r = this.g = this.b = this.a = 0;
return true;
}
return !!color;
@ -1335,30 +1347,30 @@ function LinearGradientContainer(imageData) {
if (hasDirection) {
imageData.args[0].split(" ").reverse().forEach(function(position) {
switch(position) {
case "left":
this.x0 = 0;
this.x1 = 1;
break;
case "top":
this.y0 = 0;
this.y1 = 1;
break;
case "right":
this.x0 = 1;
this.x1 = 0;
break;
case "bottom":
this.y0 = 1;
this.y1 = 0;
break;
case "to":
var y0 = this.y0;
var x0 = this.x0;
this.y0 = this.y1;
this.x0 = this.x1;
this.x1 = x0;
this.y1 = y0;
break;
case "left":
this.x0 = 0;
this.x1 = 1;
break;
case "top":
this.y0 = 0;
this.y1 = 1;
break;
case "right":
this.x0 = 1;
this.x1 = 0;
break;
case "bottom":
this.y0 = 1;
this.y1 = 0;
break;
case "to":
var y0 = this.y0;
var x0 = this.x0;
this.y0 = this.y1;
this.x0 = this.x1;
this.x1 = x0;
this.y1 = y0;
break;
}
}, this);
} else {
@ -1369,7 +1381,7 @@ function LinearGradientContainer(imageData) {
this.colorStops = imageData.args.slice(hasDirection ? 1 : 0).map(function(colorStop) {
var colorStopMatch = colorStop.match(this.stepRegExp);
return {
color: colorStopMatch[1],
color: new Color(colorStopMatch[1]),
stop: colorStopMatch[3] === "%" ? colorStopMatch[2] / 100 : null
};
}, this);
@ -1417,6 +1429,7 @@ function NodeContainer(node, parent) {
this.offsetBounds = null;
this.visible = null;
this.computedStyles = null;
this.colors = {};
this.styles = {};
this.backgroundImages = null;
this.transformData = null;
@ -1484,6 +1497,10 @@ NodeContainer.prototype.cssInt = function(attribute) {
return (isNaN(value)) ? 0 : value; // borders in old IE are throwing 'medium' for demo.html
};
NodeContainer.prototype.color = function(attribute) {
return this.colors[attribute] || (this.colors[attribute] = new Color(this.css(attribute)));
};
NodeContainer.prototype.cssFloat = function(attribute) {
var value = parseFloat(this.css(attribute));
return (isNaN(value)) ? 0 : value;
@ -1597,7 +1614,7 @@ NodeContainer.prototype.parseTextShadows = function() {
for (var i = 0; shadows && (i < shadows.length); i++) {
var s = shadows[i].match(this.TEXT_SHADOW_VALUES);
results.push({
color: s[0],
color: new Color(s[0]),
offsetX: s[1] ? parseFloat(s[1].replace('px', '')) : 0,
offsetY: s[2] ? parseFloat(s[2].replace('px', '')) : 0,
blur: s[3] ? s[3].replace('px', '') : 0
@ -1817,8 +1834,8 @@ function NodeParser(element, renderer, support, imageLoader, options) {
var parent = new NodeContainer(element, null);
if (element === element.ownerDocument.documentElement) {
// http://www.w3.org/TR/css3-background/#special-backgrounds
var canvasBackground = new NodeContainer(this.renderer.isTransparent(parent.css('backgroundColor')) ? element.ownerDocument.body : element.ownerDocument.documentElement, null);
renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.css('backgroundColor'));
var canvasBackground = new NodeContainer(parent.color('backgroundColor').isTransparent() ? element.ownerDocument.body : element.ownerDocument.documentElement, null);
renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.color('backgroundColor'));
}
parent.visibile = parent.isElementVisible();
this.createPseudoHideStyles(element.ownerDocument);
@ -2001,7 +2018,7 @@ NodeParser.prototype.createStackingContexts = function() {
};
NodeParser.prototype.isBodyWithTransparentRoot = function(container) {
return container.node.nodeName === "BODY" && this.renderer.isTransparent(container.parent.css('backgroundColor'));
return container.node.nodeName === "BODY" && container.parent.color('backgroundColor').isTransparent();
};
NodeParser.prototype.isRootElement = function(container) {
@ -2161,16 +2178,16 @@ NodeParser.prototype.paintCheckbox = function(container) {
var r = [3, 3];
var radius = [r, r, r, r];
var borders = [1,1,1,1].map(function(w) {
return {color: '#A5A5A5', width: w};
return {color: new Color('#A5A5A5'), width: w};
});
var borderPoints = calculateCurvePoints(bounds, radius, borders);
this.renderer.clip(container.backgroundClip, function() {
this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, "#DEDEDE");
this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, new Color("#DEDEDE"));
this.renderer.renderBorders(calculateBorders(borders, bounds, borderPoints, radius));
if (container.node.checked) {
this.renderer.font('#424242', 'normal', 'normal', 'bold', (size - 3) + "px", 'arial');
this.renderer.font(new Color('#424242'), 'normal', 'normal', 'bold', (size - 3) + "px", 'arial');
this.renderer.text("\u2714", bounds.left + size / 6, bounds.top + size - 1);
}
}, this);
@ -2182,9 +2199,9 @@ NodeParser.prototype.paintRadio = function(container) {
var size = Math.min(bounds.width, bounds.height) - 2;
this.renderer.clip(container.backgroundClip, function() {
this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, '#DEDEDE', 1, '#A5A5A5');
this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, new Color('#DEDEDE'), 1, new Color('#A5A5A5'));
if (container.node.checked) {
this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), '#424242');
this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), new Color('#424242'));
}
}, this);
};
@ -2229,7 +2246,7 @@ NodeParser.prototype.paintText = function(container) {
var family = container.parent.css('fontFamily');
var shadows = container.parent.parseTextShadows();
this.renderer.font(container.parent.css('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);
this.renderer.font(container.parent.color('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);
if (shadows.length) {
// TODO: support multiple text shadows
this.renderer.fontShadow(shadows[0].color, shadows[0].offsetX, shadows[0].offsetY, shadows[0].blur);
@ -2252,14 +2269,14 @@ NodeParser.prototype.renderTextDecoration = function(container, bounds, metrics)
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.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.css("color"));
this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.color("color"));
break;
case "overline":
this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.css("color"));
this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.color("color"));
break;
case "line-through":
// TODO try and find exact position for line-through
this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.css("color"));
this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.color("color"));
break;
}
};
@ -2270,7 +2287,7 @@ NodeParser.prototype.parseBorders = function(container) {
var borders = ["Top", "Right", "Bottom", "Left"].map(function(side) {
return {
width: container.cssInt('border' + side + 'Width'),
color: container.css('border' + side + 'Color'),
color: container.color('border' + side + 'Color'),
args: null
};
});
@ -2785,9 +2802,9 @@ Renderer.prototype.renderBackground = function(container, bounds, borderData) {
};
Renderer.prototype.renderBackgroundColor = function(container, bounds) {
var color = container.css("backgroundColor");
if (!this.isTransparent(color)) {
this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, container.css("backgroundColor"));
var color = container.color("backgroundColor");
if (!color.isTransparent()) {
this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, color);
}
};
@ -2796,7 +2813,7 @@ Renderer.prototype.renderBorders = function(borders) {
};
Renderer.prototype.renderBorder = function(data) {
if (!this.isTransparent(data.color) && data.args !== null) {
if (!data.color.isTransparent() && data.args !== null) {
this.drawShape(data.args, data.color);
}
};
@ -2805,27 +2822,27 @@ Renderer.prototype.renderBackgroundImage = function(container, bounds, borderDat
var backgroundImages = container.parseBackgroundImages();
backgroundImages.reverse().forEach(function(backgroundImage, index, arr) {
switch(backgroundImage.method) {
case "url":
var image = this.images.get(backgroundImage.args[0]);
if (image) {
this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);
} else {
log("Error loading background-image", backgroundImage.args[0]);
}
break;
case "linear-gradient":
case "gradient":
var gradientImage = this.images.get(backgroundImage.value);
if (gradientImage) {
this.renderBackgroundGradient(gradientImage, bounds, borderData);
} else {
log("Error loading background-image", backgroundImage.args[0]);
}
break;
case "none":
break;
default:
log("Unknown background-image type", backgroundImage.args[0]);
case "url":
var image = this.images.get(backgroundImage.args[0]);
if (image) {
this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);
} else {
log("Error loading background-image", backgroundImage.args[0]);
}
break;
case "linear-gradient":
case "gradient":
var gradientImage = this.images.get(backgroundImage.value);
if (gradientImage) {
this.renderBackgroundGradient(gradientImage, bounds, borderData);
} else {
log("Error loading background-image", backgroundImage.args[0]);
}
break;
case "none":
break;
default:
log("Unknown background-image type", backgroundImage.args[0]);
}
}, this);
};
@ -2852,10 +2869,6 @@ Renderer.prototype.renderBackgroundRepeating = function(container, bounds, image
}
};
Renderer.prototype.isTransparent = function(color) {
return (!color || color === "transparent" || color === "rgba(0, 0, 0, 0)");
};
function StackingContext(hasOwnStacking, opacity, element, parent) {
NodeContainer.call(this, element, parent);
this.ownStacking = hasOwnStacking;
@ -3103,8 +3116,8 @@ function CanvasRenderer(width, height) {
CanvasRenderer.prototype = Object.create(Renderer.prototype);
CanvasRenderer.prototype.setFillStyle = function(color) {
this.ctx.fillStyle = color;
CanvasRenderer.prototype.setFillStyle = function(fillStyle) {
this.ctx.fillStyle = fillStyle;
return this.ctx;
};

File diff suppressed because one or more lines are too long

View File

@ -12,6 +12,10 @@ function Color(value) {
this.hex3(value);
}
Color.prototype.isTransparent = function() {
return this.a === 0;
};
var _hex3 = /^#([a-f0-9]{3})$/i;
Color.prototype.hex3 = function(value) {
@ -62,6 +66,11 @@ Color.prototype.rgba = function(value) {
return match !== null;
};
Color.prototype.toString = function() {
return this.a !== null ?
"rgba(" + [this.r, this.g, this.b, this.a].join(",") + ")" :
"rgb(" + [this.r, this.g, this.b].join(",") + ")";
};
Color.prototype.namedColor = function(value) {
var color = colors[value.toLowerCase()];
@ -69,6 +78,9 @@ Color.prototype.namedColor = function(value) {
this.r = color[0];
this.g = color[1];
this.b = color[2];
} else if (value.toLowerCase() === "transparent") {
this.r = this.g = this.b = this.a = 0;
return true;
}
return !!color;

View File

@ -7,30 +7,30 @@ function LinearGradientContainer(imageData) {
if (hasDirection) {
imageData.args[0].split(" ").reverse().forEach(function(position) {
switch(position) {
case "left":
this.x0 = 0;
this.x1 = 1;
break;
case "top":
this.y0 = 0;
this.y1 = 1;
break;
case "right":
this.x0 = 1;
this.x1 = 0;
break;
case "bottom":
this.y0 = 1;
this.y1 = 0;
break;
case "to":
var y0 = this.y0;
var x0 = this.x0;
this.y0 = this.y1;
this.x0 = this.x1;
this.x1 = x0;
this.y1 = y0;
break;
case "left":
this.x0 = 0;
this.x1 = 1;
break;
case "top":
this.y0 = 0;
this.y1 = 1;
break;
case "right":
this.x0 = 1;
this.x1 = 0;
break;
case "bottom":
this.y0 = 1;
this.y1 = 0;
break;
case "to":
var y0 = this.y0;
var x0 = this.x0;
this.y0 = this.y1;
this.x0 = this.x1;
this.x1 = x0;
this.y1 = y0;
break;
}
}, this);
} else {
@ -41,7 +41,7 @@ function LinearGradientContainer(imageData) {
this.colorStops = imageData.args.slice(hasDirection ? 1 : 0).map(function(colorStop) {
var colorStopMatch = colorStop.match(this.stepRegExp);
return {
color: colorStopMatch[1],
color: new Color(colorStopMatch[1]),
stop: colorStopMatch[3] === "%" ? colorStopMatch[2] / 100 : null
};
}, this);

View File

@ -9,6 +9,7 @@ function NodeContainer(node, parent) {
this.offsetBounds = null;
this.visible = null;
this.computedStyles = null;
this.colors = {};
this.styles = {};
this.backgroundImages = null;
this.transformData = null;
@ -76,6 +77,10 @@ NodeContainer.prototype.cssInt = function(attribute) {
return (isNaN(value)) ? 0 : value; // borders in old IE are throwing 'medium' for demo.html
};
NodeContainer.prototype.color = function(attribute) {
return this.colors[attribute] || (this.colors[attribute] = new Color(this.css(attribute)));
};
NodeContainer.prototype.cssFloat = function(attribute) {
var value = parseFloat(this.css(attribute));
return (isNaN(value)) ? 0 : value;
@ -189,7 +194,7 @@ NodeContainer.prototype.parseTextShadows = function() {
for (var i = 0; shadows && (i < shadows.length); i++) {
var s = shadows[i].match(this.TEXT_SHADOW_VALUES);
results.push({
color: s[0],
color: new Color(s[0]),
offsetX: s[1] ? parseFloat(s[1].replace('px', '')) : 0,
offsetY: s[2] ? parseFloat(s[2].replace('px', '')) : 0,
blur: s[3] ? s[3].replace('px', '') : 0

View File

@ -9,8 +9,8 @@ function NodeParser(element, renderer, support, imageLoader, options) {
var parent = new NodeContainer(element, null);
if (element === element.ownerDocument.documentElement) {
// http://www.w3.org/TR/css3-background/#special-backgrounds
var canvasBackground = new NodeContainer(this.renderer.isTransparent(parent.css('backgroundColor')) ? element.ownerDocument.body : element.ownerDocument.documentElement, null);
renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.css('backgroundColor'));
var canvasBackground = new NodeContainer(parent.color('backgroundColor').isTransparent() ? element.ownerDocument.body : element.ownerDocument.documentElement, null);
renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.color('backgroundColor'));
}
parent.visibile = parent.isElementVisible();
this.createPseudoHideStyles(element.ownerDocument);
@ -193,7 +193,7 @@ NodeParser.prototype.createStackingContexts = function() {
};
NodeParser.prototype.isBodyWithTransparentRoot = function(container) {
return container.node.nodeName === "BODY" && this.renderer.isTransparent(container.parent.css('backgroundColor'));
return container.node.nodeName === "BODY" && container.parent.color('backgroundColor').isTransparent();
};
NodeParser.prototype.isRootElement = function(container) {
@ -353,16 +353,16 @@ NodeParser.prototype.paintCheckbox = function(container) {
var r = [3, 3];
var radius = [r, r, r, r];
var borders = [1,1,1,1].map(function(w) {
return {color: '#A5A5A5', width: w};
return {color: new Color('#A5A5A5'), width: w};
});
var borderPoints = calculateCurvePoints(bounds, radius, borders);
this.renderer.clip(container.backgroundClip, function() {
this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, "#DEDEDE");
this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, new Color("#DEDEDE"));
this.renderer.renderBorders(calculateBorders(borders, bounds, borderPoints, radius));
if (container.node.checked) {
this.renderer.font('#424242', 'normal', 'normal', 'bold', (size - 3) + "px", 'arial');
this.renderer.font(new Color('#424242'), 'normal', 'normal', 'bold', (size - 3) + "px", 'arial');
this.renderer.text("\u2714", bounds.left + size / 6, bounds.top + size - 1);
}
}, this);
@ -374,9 +374,9 @@ NodeParser.prototype.paintRadio = function(container) {
var size = Math.min(bounds.width, bounds.height) - 2;
this.renderer.clip(container.backgroundClip, function() {
this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, '#DEDEDE', 1, '#A5A5A5');
this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, new Color('#DEDEDE'), 1, new Color('#A5A5A5'));
if (container.node.checked) {
this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), '#424242');
this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), new Color('#424242'));
}
}, this);
};
@ -421,7 +421,7 @@ NodeParser.prototype.paintText = function(container) {
var family = container.parent.css('fontFamily');
var shadows = container.parent.parseTextShadows();
this.renderer.font(container.parent.css('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);
this.renderer.font(container.parent.color('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);
if (shadows.length) {
// TODO: support multiple text shadows
this.renderer.fontShadow(shadows[0].color, shadows[0].offsetX, shadows[0].offsetY, shadows[0].blur);
@ -444,14 +444,14 @@ NodeParser.prototype.renderTextDecoration = function(container, bounds, metrics)
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.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.css("color"));
this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.color("color"));
break;
case "overline":
this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.css("color"));
this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.color("color"));
break;
case "line-through":
// TODO try and find exact position for line-through
this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.css("color"));
this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.color("color"));
break;
}
};
@ -462,7 +462,7 @@ NodeParser.prototype.parseBorders = function(container) {
var borders = ["Top", "Right", "Bottom", "Left"].map(function(side) {
return {
width: container.cssInt('border' + side + 'Width'),
color: container.css('border' + side + 'Color'),
color: container.color('border' + side + 'Color'),
args: null
};
});

View File

@ -36,9 +36,9 @@ Renderer.prototype.renderBackground = function(container, bounds, borderData) {
};
Renderer.prototype.renderBackgroundColor = function(container, bounds) {
var color = container.css("backgroundColor");
if (!this.isTransparent(color)) {
this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, container.css("backgroundColor"));
var color = container.color("backgroundColor");
if (!color.isTransparent()) {
this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, color);
}
};
@ -47,7 +47,7 @@ Renderer.prototype.renderBorders = function(borders) {
};
Renderer.prototype.renderBorder = function(data) {
if (!this.isTransparent(data.color) && data.args !== null) {
if (!data.color.isTransparent() && data.args !== null) {
this.drawShape(data.args, data.color);
}
};
@ -56,27 +56,27 @@ Renderer.prototype.renderBackgroundImage = function(container, bounds, borderDat
var backgroundImages = container.parseBackgroundImages();
backgroundImages.reverse().forEach(function(backgroundImage, index, arr) {
switch(backgroundImage.method) {
case "url":
var image = this.images.get(backgroundImage.args[0]);
if (image) {
this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);
} else {
log("Error loading background-image", backgroundImage.args[0]);
}
break;
case "linear-gradient":
case "gradient":
var gradientImage = this.images.get(backgroundImage.value);
if (gradientImage) {
this.renderBackgroundGradient(gradientImage, bounds, borderData);
} else {
log("Error loading background-image", backgroundImage.args[0]);
}
break;
case "none":
break;
default:
log("Unknown background-image type", backgroundImage.args[0]);
case "url":
var image = this.images.get(backgroundImage.args[0]);
if (image) {
this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);
} else {
log("Error loading background-image", backgroundImage.args[0]);
}
break;
case "linear-gradient":
case "gradient":
var gradientImage = this.images.get(backgroundImage.value);
if (gradientImage) {
this.renderBackgroundGradient(gradientImage, bounds, borderData);
} else {
log("Error loading background-image", backgroundImage.args[0]);
}
break;
case "none":
break;
default:
log("Unknown background-image type", backgroundImage.args[0]);
}
}, this);
};
@ -102,7 +102,3 @@ Renderer.prototype.renderBackgroundRepeating = function(container, bounds, image
break;
}
};
Renderer.prototype.isTransparent = function(color) {
return (!color || color === "transparent" || color === "rgba(0, 0, 0, 0)");
};

View File

@ -17,8 +17,8 @@ function CanvasRenderer(width, height) {
CanvasRenderer.prototype = Object.create(Renderer.prototype);
CanvasRenderer.prototype.setFillStyle = function(color) {
this.ctx.fillStyle = color;
CanvasRenderer.prototype.setFillStyle = function(fillStyle) {
this.ctx.fillStyle = fillStyle;
return this.ctx;
};

View File

@ -16,11 +16,13 @@
it("bisque", function () {
var c = new Color("bisque");
assertColor(c, 255, 228, 196, null);
expect(c.isTransparent()).to.equal(false);
});
it("BLUE", function () {
var c = new Color("BLUE");
assertColor(c, 0, 0, 255, null);
expect(c.isTransparent()).to.equal(false);
});
});
@ -28,33 +30,39 @@
it("rgb(1,3,5)", function () {
var c = new Color("rgb(1,3,5)");
assertColor(c, 1, 3, 5, null);
expect(c.isTransparent()).to.equal(false);
});
it("rgb(222, 111, 50)", function () {
var c = new Color("rgb(222, 111, 50)");
assertColor(c, 222, 111, 50, null);
expect(c.isTransparent()).to.equal(false);
});
it("rgb( 222, 111 , 50)", function () {
var c = new Color("rgb(222 , 111 , 50)");
assertColor(c, 222, 111, 50, null);
expect(c.isTransparent()).to.equal(false);
});
});
describe("rgba()", function() {
it("rgba(200,3,5,0)", function () {
var c = new Color("rgba(200,3,5,0)");
assertColor(c, 200, 3, 5, 0);
it("rgba(200,3,5,1)", function () {
var c = new Color("rgba(200,3,5,1)");
assertColor(c, 200, 3, 5, 1);
expect(c.isTransparent()).to.equal(false);
});
it("rgba(222, 111, 50, 0.22)", function () {
var c = new Color("rgba(222, 111, 50, 0.22)");
assertColor(c, 222, 111, 50, 0.22);
expect(c.isTransparent()).to.equal(false);
});
it("rgba( 222, 111 , 50, 0.123 )", function () {
var c = new Color("rgba(222 , 111 , 50, 0.123)");
assertColor(c, 222, 111, 50, 0.123);
expect(c.isTransparent()).to.equal(false);
});
});
@ -62,16 +70,33 @@
it("#7FFFD4", function () {
var c = new Color("#7FFFD4");
assertColor(c, 127, 255, 212, null);
expect(c.isTransparent()).to.equal(false);
});
it("#f0ffff", function () {
var c = new Color("#f0ffff");
assertColor(c, 240, 255, 255, null);
expect(c.isTransparent()).to.equal(false);
});
it("#fff", function () {
var c = new Color("#fff");
assertColor(c, 255, 255, 255, null);
expect(c.isTransparent()).to.equal(false);
});
});
describe("transparency", function() {
it("transparent", function () {
var c = new Color("transparent");
assertColor(c, 0, 0, 0, 0);
expect(c.isTransparent()).to.equal(true);
});
it("rgba(255,255,255,0)", function () {
var c = new Color("rgba(255,255,255,0)");
assertColor(c, 255, 255, 255, 0);
expect(c.isTransparent()).to.equal(true);
});
});
});

View File

@ -12,7 +12,7 @@ var h2cSelector, h2cOptions;
}
var sources = ['log', 'punycode/punycode', 'core', 'nodecontainer', 'pseudoelementcontainer', 'stackingcontext', 'textcontainer', 'support', 'imagecontainer', 'dummyimagecontainer', 'proxyimagecontainer', 'gradientcontainer',
'lineargradientcontainer', 'webkitgradientcontainer', 'svgcontainer', 'svgnodecontainer', 'imageloader', 'nodeparser', 'font', 'fontmetrics', 'renderer', 'promise', 'xhr', 'framecontainer', 'proxy', 'renderers/canvas'];
'lineargradientcontainer', 'webkitgradientcontainer', 'svgcontainer', 'svgnodecontainer', 'imageloader', 'nodeparser', 'font', 'fontmetrics', 'renderer', 'promise', 'xhr', 'framecontainer', 'proxy', 'color', 'renderers/canvas'];
['/tests/assets/jquery-1.6.2'].concat(window.location.search === "?selenium" ? ['/dist/html2canvas'] : sources.map(function(src) { return '/src/' + src; })).forEach(appendScript);