Oops, forgot to add vars. And also fix for IE getBBox for text elements.
[raphael] / raphael.js
index b15fb90..3620fc8 100644 (file)
@@ -454,7 +454,7 @@ function Raphael() {
 
     // SVG
     if (R.svg) {
-        thePath = function (params, pathString, SVG) {
+        var thePath = function (params, pathString, SVG) {
             var el = document.createElementNS(SVG.svgns, "path");
             el.setAttribute("fill", "none");
             if (SVG.canvas) {
@@ -640,7 +640,7 @@ function Raphael() {
             }
             return p;
         };
-        addGrdientFill = function (o, gradient, SVG) {
+        var addGrdientFill = function (o, gradient, SVG) {
             var el = document.createElementNS(SVG.svgns, gradient.type + "Gradient");
             el.id = "raphael-gradient-" + Raphael.idGenerator++;
             if (gradient.vector && gradient.vector.length) {
@@ -661,13 +661,13 @@ function Raphael() {
             };
             o.setAttribute("fill", "url(#" + el.id + ")");
         };
-        updatePosition = function (o) {
+        var updatePosition = function (o) {
             if (o.pattern) {
                 var bbox = o.node.getBBox();
                 o.pattern.setAttribute("patternTransform", "translate(" + [bbox.x, bbox.y].join(",") + ")");
             }
         };
-        setFillAndStroke = function (o, params) {
+        var setFillAndStroke = function (o, params) {
             var dasharray = {
                 "-": [3, 1],
                 ".": [1, 1],
@@ -916,7 +916,7 @@ function Raphael() {
             element.node.parentNode.insertBefore(this.node, element.node);
             return this;
         };
-        theCircle = function (svg, x, y, r) {
+        var theCircle = function (svg, x, y, r) {
             var el = document.createElementNS(svg.svgns, "circle");
             el.setAttribute("cx", x);
             el.setAttribute("cy", y);
@@ -935,7 +935,7 @@ function Raphael() {
             res.type = "circle";
             return res;
         };
-        theRect = function (svg, x, y, w, h, r) {
+        var theRect = function (svg, x, y, w, h, r) {
             var el = document.createElementNS(svg.svgns, "rect");
             el.setAttribute("x", x);
             el.setAttribute("y", y);
@@ -963,7 +963,7 @@ function Raphael() {
             res.type = "rect";
             return res;
         };
-        theEllipse = function (svg, x, y, rx, ry) {
+        var theEllipse = function (svg, x, y, rx, ry) {
             var el = document.createElementNS(svg.svgns, "ellipse");
             el.setAttribute("cx", x);
             el.setAttribute("cy", y);
@@ -984,7 +984,7 @@ function Raphael() {
             res.type = "ellipse";
             return res;
         };
-        theImage = function (svg, src, x, y, w, h) {
+        var theImage = function (svg, src, x, y, w, h) {
             var el = document.createElementNS(svg.svgns, "image");
             el.setAttribute("x", x);
             el.setAttribute("y", y);
@@ -1004,12 +1004,11 @@ function Raphael() {
             res.type = "image";
             return res;
         };
-        theText = function (svg, x, y, text) {
+        var theText = function (svg, x, y, text) {
             var el = document.createElementNS(svg.svgns, "text");
             el.setAttribute("x", x);
             el.setAttribute("y", y);
             el.setAttribute("text-anchor", "middle");
-            el.setAttribute("fill", "#000");
             if (text) {
                 el.appendChild(document.createTextNode(text));
             }
@@ -1020,11 +1019,11 @@ function Raphael() {
             res.attrs = res.attrs || {};
             res.attrs.x = x;
             res.attrs.y = y;
-            res.attrs.fill = "#000";
             res.type = "text";
+            setFillAndStroke(res, {font: '10px "Arial"', stroke: "none", fill: "#000"});
             return res;
         };
-        theGroup = function (svg) {
+        var theGroup = function (svg) {
             var el = document.createElementNS(svg.svgns, "g");
             if (svg.canvas) {
                 svg.canvas.appendChild(el);
@@ -1353,8 +1352,9 @@ function Raphael() {
             }
             return p;
         };
-        setFillAndStroke = function (o, params) {
-            var s = o[0].style;
+        var setFillAndStroke = function (o, params) {
+            var s = o.node.style,
+                res = o;
             o.attrs = o.attrs || {};
             for (var par in params) {
                 o.attrs[par] = params[par];
@@ -1379,10 +1379,11 @@ function Raphael() {
                 o.node.filterOpacity = " progid:DXImageTransform.Microsoft.Alpha(opacity=" + (params.opacity * 100) + ")";
                 o.node.style.filter = (o.node.filterMatrix || "") + (o.node.filterOpacity || "");
             }
+            params.font && (s.font = params.font);
             params["font-family"] && (s.fontFamily = params["font-family"]);
             params["font-size"] && (s.fontSize = params["font-size"]);
-            params["font"] && (s.font = params["font"]);
             params["font-weight"] && (s.fontWeight = params["font-weight"]);
+            params["font-style"] && (s.fontStyle = params["font-style"]);
             if (typeof params.opacity != "undefined" || typeof params["stroke-width"] != "undefined" || typeof params.fill != "undefined" || typeof params.stroke != "undefined") {
                 o = o.shape || o.node;
                 var fill = (o.getElementsByTagName("fill") && o.getElementsByTagName("fill")[0]) || document.createElement("rvml:fill");
@@ -1439,8 +1440,35 @@ function Raphael() {
                 }
                 o.appendChild(stroke);
             }
+            if (res.type == "text") {
+                var span = document.createElement("span"),
+                    s = span.style;
+                res.attrs.font && (s.font = res.attrs.font);
+                res.attrs["font-family"] && (s.fontFamily = res.attrs["font-family"]);
+                res.attrs["font-size"] && (s.fontSize = res.attrs["font-size"]);
+                res.attrs["font-weight"] && (s.fontWeight = res.attrs["font-weight"]);
+                res.attrs["font-style"] && (s.fontStyle = res.attrs["font-style"]);
+                res.node.parentNode.appendChild(span);
+                span.innerText = res.node.string;
+                res.W = res.attrs.w = span.offsetWidth;
+                res.H = res.attrs.h = span.offsetHeight;
+                res.X = res.attrs.x - Math.round(res.W / 2);
+                res.Y = res.attrs.y - Math.round(res.H / 2);
+                res.node.parentNode.removeChild(span);
+            }
+        };
+        var getAngle = function (a, b, c, d) {
+            var angle = Math.round(Math.atan((parseFloat(c, 10) - parseFloat(a, 10)) / (parseFloat(d, 10) - parseFloat(b, 10))) * 57.29) || 0;
+            if (!angle && parseFloat(a, 10) < parseFloat(b, 10)) {
+                angle = 180;
+            }
+            angle -= 180;
+            if (angle < 0) {
+                angle += 360;
+            }
+            return angle;
         };
-        addGrdientFill = function (o, gradient) {
+        var addGrdientFill = function (o, gradient) {
             o.attrs = o.attrs || {};
             o.attrs.gradient = gradient;
             o = o.shape || o[0];
@@ -1466,8 +1494,8 @@ function Raphael() {
                         colors.push(gradient.dots[i].offset + " " + gradient.dots[i].color);
                     }
                 };
-                var fillOpacity = gradient.dots[0].opacity || 1;
-                var fillOpacity2 = gradient.dots[gradient.dots.length - 1].opacity || 1;
+                var fillOpacity = typeof gradient.dots[0].opacity == "undefined" ? 1 : gradient.dots[0].opacity;
+                var fillOpacity2 = typeof gradient.dots[gradient.dots.length - 1].opacity == "undefined" ? 1 : gradient.dots[gradient.dots.length - 1].opacity;
                 if (colors) {
                     fill.colors.value = colors.join(",");
                     fillOpacity2 += fillOpacity;
@@ -1477,8 +1505,7 @@ function Raphael() {
                 fill.setAttribute("opacity", fillOpacity);
                 fill.setAttribute("opacity2", fillOpacity2);
                 if (gradient.vector) {
-                    var angle = Math.round(Math.atan((parseFloat(gradient.vector[3], 10) - parseFloat(gradient.vector[1], 10)) / (parseFloat(gradient.vector[2], 10) - parseFloat(gradient.vector[0], 10))) * 57.29) || 0;
-                    fill.angle = 270 - angle;
+                    fill.angle = getAngle.apply(null, gradient.vector);
                 }
                 if (gradient.type.toLowerCase() == "radial") {
                     fill.focus = "100%";
@@ -1520,7 +1547,7 @@ function Raphael() {
         };
         Element.prototype.setBox = function (params) {
             var gs = this.Group.style,
-                os = this[0].style;
+                os = (this.shape && this.shape.style) || this.node.style;
             for (var i in params) {
                 this.attrs[i] = params[i];
             }
@@ -1546,7 +1573,11 @@ function Raphael() {
                     break;
                 case "text":
                     this.textpath.v = ["m", Math.round(attr.x), ", ", Math.round(attr.y - 2), "l", Math.round(attr.x) + 1, ", ", Math.round(attr.y - 2)].join("");
-                    return;
+                    x = attr.x - Math.round(this.W / 2);
+                    y = attr.y - this.H / 2;
+                    w = this.W;
+                    h = this.H;
+                    break;
                 case "path":
                     if (!this.attrs.path) {
                         x = 0;
@@ -1568,13 +1599,13 @@ function Raphael() {
                     h = this.vml.height;
                     break;
             }
-            if (this.type == "path") {
+            if (this.type == "path" || this.type == "text") {
                 var left = Math.round(this.vml.width / 2 - w / 2 - x),
                     top = Math.round(this.vml.height / 2 - h / 2 - y);
                 gs.left = - left + "px";
                 gs.top = - top + "px";
-                this.X = left;
-                this.Y = top;
+                this.X = this.type == "text" ? x : left;
+                this.Y = this.type == "text" ? y : top;
                 this.W = w;
                 this.H = h;
                 os.top = top + "px";
@@ -1649,7 +1680,7 @@ function Raphael() {
                 };
                 return values;
             }
-            if (this[0].tagName.toLowerCase() == "group") {
+            if (this.node.tagName.toLowerCase() == "group") {
                 var children = this[0].childNodes;
                 this.attrs = this.attrs || {};
                 if (arguments.length == 2) {
@@ -1672,17 +1703,17 @@ function Raphael() {
                     params = arguments[0];
                 }
                 if (params) {
-                    setFillAndStroke(this, params);
-                    this.setBox(params);
                     if (params.gradient) {
                         addGrdientFill(this, params.gradient);
                     }
                     if (params.text && this.type == "text") {
-                        this[0].string = params.text;
+                        this.node.string = params.text;
                     }
                     if (params.id) {
-                        this[0].id = params.id;
+                        this.node.id = params.id;
                     }
+                    setFillAndStroke(this, params);
+                    this.setBox(params);
                 }
             }
             return this;
@@ -1709,21 +1740,21 @@ function Raphael() {
             element.Group.parentNode.insertBefore(this.Group, element.Group);
             return this;
         };
-        theCircle = function (vml, x, y, r) {
+        var theCircle = function (vml, x, y, r) {
             var g = document.createElement("rvml:group");
             var o = document.createElement("rvml:oval");
             g.appendChild(o);
             vml.canvas.appendChild(g);
             var res = new Element(o, g, vml);
+            res.type = "circle";
             setFillAndStroke(res, {stroke: "#000", fill: "none"});
             res.setBox({x: x - r, y: y - r, width: r * 2, height: r * 2});
             res.attrs.cx = x;
             res.attrs.cy = y;
             res.attrs.r = r;
-            res.type = "circle";
             return res;
         };
-        theRect = function (vml, x, y, w, h, r) {
+        var theRect = function (vml, x, y, w, h, r) {
             var g = document.createElement("rvml:group");
             var o = document.createElement(r ? "rvml:roundrect" : "rvml:rect");
             if (r) {
@@ -1732,6 +1763,7 @@ function Raphael() {
             g.appendChild(o);
             vml.canvas.appendChild(g);
             var res = new Element(o, g, vml);
+            res.type = "rect";
             setFillAndStroke(res, {stroke: "#000"});
             res.setBox({x: x, y: y, width: w, height: h});
             res.attrs.x = x;
@@ -1739,25 +1771,24 @@ function Raphael() {
             res.attrs.w = w;
             res.attrs.h = h;
             res.attrs.r = r;
-            res.type = "rect";
             return res;
         };
-        theEllipse = function (vml, x, y, rx, ry) {
+        var theEllipse = function (vml, x, y, rx, ry) {
             var g = document.createElement("rvml:group");
             var o = document.createElement("rvml:oval");
             g.appendChild(o);
             vml.canvas.appendChild(g);
             var res = new Element(o, g, vml);
+            res.type = "ellipse";
             setFillAndStroke(res, {stroke: "#000"});
             res.setBox({x: x - rx, y: y - ry, width: rx * 2, height: ry * 2});
             res.attrs.cx = x;
             res.attrs.cy = y;
             res.attrs.rx = rx;
             res.attrs.ry = ry;
-            res.type = "ellipse";
             return res;
         };
-        theImage = function (vml, src, x, y, w, h) {
+        var theImage = function (vml, src, x, y, w, h) {
             var g = document.createElement("rvml:group");
             var o = document.createElement("rvml:image");
             o.src = src;
@@ -1772,8 +1803,7 @@ function Raphael() {
             res.attrs.h = h;
             return res;
         };
-        theText = function (vml, x, y, text) {
-            // @TODO: setTheBox
+        var theText = function (vml, x, y, text) {
             var g = document.createElement("rvml:group"), gs = g.style;
             var el = document.createElement("rvml:shape"), ol = el.style;
             var path = document.createElement("rvml:path"), ps = path.style;
@@ -1803,10 +1833,10 @@ function Raphael() {
             res.attrs.y = y;
             res.attrs.w = 1;
             res.attrs.h = 1;
-            setFillAndStroke(res, {stroke: "none", fill: "#000"});
+            setFillAndStroke(res, {font: '10px "Arial"', stroke: "none", fill: "#000"});
             return res;
         };
-        theGroup = function (vml) {
+        var theGroup = function (vml) {
             return this;
         };
         R._create = function () {