From 39e081b711b9f1a2f9825a3430945403045464b3 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Sat, 5 Sep 2015 15:49:02 -0700 Subject: [PATCH] Make canvas2svg work with jsdom --- canvas2svg.js | 106 ++++++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 50 deletions(-) diff --git a/canvas2svg.js b/canvas2svg.js index 038e6a8..d79d6bc 100644 --- a/canvas2svg.js +++ b/canvas2svg.js @@ -72,29 +72,6 @@ return mapping[textBaseline] || mapping.alphabetic; } - /** - * Creates the specified svg element - * @private - */ - function createElement(elementName, properties, resetFill) { - if (typeof properties === "undefined") { - properties = {}; - } - - var element = document.createElementNS("http://www.w3.org/2000/svg", elementName), - keys = Object.keys(properties), i, key; - if(resetFill) { - //if fill or stroke is not specified, the svg element should not display. By default SVG's fill is black. - element.setAttribute("fill", "none"); - element.setAttribute("stroke", "none"); - } - for(i=0; i 1) { @@ -258,7 +237,8 @@ this.enableMirroring = options.enableMirroring !== undefined ? options.enableMirroring : defaultOptions.enableMirroring; this.canvas = this; ///point back to this instance! - this.__canvas = document.createElement("canvas"); + this.__document = options.document || document; + this.__canvas = this.__document.createElement("canvas"); this.__ctx = this.__canvas.getContext("2d"); this.__setDefaultStyles(); @@ -266,7 +246,7 @@ this.__groupStack = []; //the root svg element - this.__root = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + this.__root = this.__document.createElementNS("http://www.w3.org/2000/svg", "svg"); this.__root.setAttribute("version", 1.1); this.__root.setAttribute("xmlns", "http://www.w3.org/2000/svg"); this.__root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); @@ -277,14 +257,38 @@ this.__ids = {}; //defs tag - this.__defs = document.createElementNS("http://www.w3.org/2000/svg", "defs"); + this.__defs = this.__document.createElementNS("http://www.w3.org/2000/svg", "defs"); this.__root.appendChild(this.__defs); //also add a group child. the svg element can't use the transform attribute - this.__currentElement = document.createElementNS("http://www.w3.org/2000/svg", "g"); + this.__currentElement = this.__document.createElementNS("http://www.w3.org/2000/svg", "g"); this.__root.appendChild(this.__currentElement); }; + + /** + * Creates the specified svg element + * @private + */ + ctx.prototype.__createElement = function (elementName, properties, resetFill) { + if (typeof properties === "undefined") { + properties = {}; + } + + var element = this.__document.createElementNS("http://www.w3.org/2000/svg", elementName), + keys = Object.keys(properties), i, key; + if(resetFill) { + //if fill or stroke is not specified, the svg element should not display. By default SVG's fill is black. + element.setAttribute("fill", "none"); + element.setAttribute("stroke", "none"); + } + for(i=0; i 0) { - var group = createElement("g"); + var group = this.__createElement("g"); parent.appendChild(group); this.__currentElement = group; } @@ -509,7 +513,7 @@ this.__currentDefaultPath = ""; this.__currentPosition = {}; - path = createElement("path", {}, true); + path = this.__createElement("path", {}, true); parent = this.__closestGroupOrSvg(); parent.appendChild(path); this.__currentElement = path; @@ -732,7 +736,7 @@ */ ctx.prototype.fillRect = function(x, y, width, height){ var rect, parent; - rect = createElement("rect", { + rect = this.__createElement("rect", { x : x, y : y, width : width, @@ -753,7 +757,7 @@ */ ctx.prototype.strokeRect = function(x, y, width, height){ var rect, parent; - rect = createElement("rect", { + rect = this.__createElement("rect", { x : x, y : y, width : width, @@ -771,7 +775,7 @@ */ ctx.prototype.clearRect = function(x, y, width, height) { var rect, parent = this.__closestGroupOrSvg(); - rect = createElement("rect", { + rect = this.__createElement("rect", { x : x, y : y, width : width, @@ -786,7 +790,7 @@ * Returns a canvas gradient object that has a reference to it's parent def */ ctx.prototype.createLinearGradient = function(x1, y1, x2, y2){ - var grad = createElement("linearGradient", { + var grad = this.__createElement("linearGradient", { id : randomString(this.__ids), x1 : x1+"px", x2 : x2+"px", @@ -795,7 +799,7 @@ "gradientUnits" : "userSpaceOnUse" }, false); this.__defs.appendChild(grad); - return new CanvasGradient(grad); + return new CanvasGradient(grad, this); }; /** @@ -803,7 +807,7 @@ * Returns a canvas gradient object that has a reference to it's parent def */ ctx.prototype.createRadialGradient = function(x0, y0, r0, x1, y1, r1){ - var grad = createElement("radialGradient", { + var grad = this.__createElement("radialGradient", { id : randomString(this.__ids), cx : x1+"px", cy : y1+"px", @@ -813,7 +817,7 @@ "gradientUnits" : "userSpaceOnUse" }, false); this.__defs.appendChild(grad); - return new CanvasGradient(grad); + return new CanvasGradient(grad, this); }; @@ -855,7 +859,7 @@ */ ctx.prototype.__wrapTextLink = function(font, element) { if(font.href) { - var a = createElement("a"); + var a = this.__createElement("a"); a.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", font.href); a.appendChild(element); return a; @@ -874,7 +878,7 @@ ctx.prototype.__applyText = function(text, x, y, action) { var font = this.__parseFont(), parent = this.__closestGroupOrSvg(), - textElement = createElement("text", { + textElement = this.__createElement("text", { "font-family" : font.family, "font-size" : font.size, "font-style" : font.style, @@ -886,7 +890,7 @@ "dominant-baseline": getDominantBaseline(this.textBaseline) }, true); - textElement.appendChild(document.createTextNode(text)); + textElement.appendChild(this.__document.createTextNode(text)); this.__currentElement = textElement; this.__applyStyleToCurrentElement(action); parent.appendChild(this.__wrapTextLink(font,textElement)); @@ -963,9 +967,9 @@ */ ctx.prototype.clip = function(){ var group = this.__closestGroupOrSvg(), - clipPath = createElement("clipPath"), + clipPath = this.__createElement("clipPath"), id = randomString(this.__ids), - newGroup = createElement("g"); + newGroup = this.__createElement("g"); group.removeChild(this.__currentElement); clipPath.setAttribute("id", id); @@ -1043,14 +1047,14 @@ this.__currentElement = currentElement; } else if(image.nodeName === "CANVAS" || image.nodeName === "IMG") { //canvas or image - svgImage = createElement("image"); + svgImage = this.__createElement("image"); svgImage.setAttribute("width", dw); svgImage.setAttribute("height", dh); svgImage.setAttribute("preserveAspectRatio", "none"); if(sx || sy || sw !== image.width || sh !== image.height) { //crop the image using a temporary canvas - canvas = document.createElement("canvas"); + canvas = this.__document.createElement("canvas"); canvas.width = dw; canvas.height = dh; context = canvas.getContext("2d"); @@ -1071,13 +1075,13 @@ * Generates a pattern tag */ ctx.prototype.createPattern = function(image, repetition){ - var pattern = document.createElementNS("http://www.w3.org/2000/svg", "pattern"), id = randomString(this.__ids), + var pattern = this.__document.createElementNS("http://www.w3.org/2000/svg", "pattern"), id = randomString(this.__ids), img; pattern.setAttribute("id", id); pattern.setAttribute("width", image.width); pattern.setAttribute("height", image.height); if(image.nodeName === "CANVAS" || image.nodeName === "IMG") { - img = document.createElementNS("http://www.w3.org/2000/svg", "image"); + img = this.__document.createElementNS("http://www.w3.org/2000/svg", "image"); img.setAttribute("width", image.width); img.setAttribute("height", image.height); img.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", @@ -1102,7 +1106,9 @@ ctx.prototype.setTransform = function(){}; //add options for alternative namespace - window.C2S = ctx; + if (typeof window === "object") { + window.C2S = ctx; + } // CommonJS/Browserify if (typeof module === "object" && typeof module.exports === "object") {