123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- ;(function() {
-
- // http://ajaxian.com/archives/the-vml-changes-in-ie-8
- // http://www.nczonline.net/blog/2010/01/19/internet-explorer-8-document-and-browser-modes/
- // http://www.louisremi.com/2009/03/30/changes-in-vml-for-ie8-or-what-feature-can-the-ie-dev-team-break-for-you-today/
-
- var vmlAttributeMap = {
- "stroke-linejoin":"joinstyle",
- "joinstyle":"joinstyle",
- "endcap":"endcap",
- "miterlimit":"miterlimit"
- };
-
- if (document.createStyleSheet) {
-
- // this is the style rule for IE7/6: it uses a CSS class, tidy.
- document.createStyleSheet().addRule(".jsplumb_vml", "behavior:url(#default#VML);position:absolute;");
-
- // these are for VML in IE8. you have to explicitly call out which elements
- // you're going to expect to support VML!
- //
- // try to avoid IE8. it is recommended you set X-UA-Compatible="IE=7" if you can.
- //
- document.createStyleSheet().addRule("jsplumb\\:textbox", "behavior:url(#default#VML);position:absolute;");
- document.createStyleSheet().addRule("jsplumb\\:oval", "behavior:url(#default#VML);position:absolute;");
- document.createStyleSheet().addRule("jsplumb\\:rect", "behavior:url(#default#VML);position:absolute;");
- document.createStyleSheet().addRule("jsplumb\\:stroke", "behavior:url(#default#VML);position:absolute;");
- document.createStyleSheet().addRule("jsplumb\\:shape", "behavior:url(#default#VML);position:absolute;");
-
- // in this page it is also mentioned that IE requires the extra arg to the namespace
- // http://www.louisremi.com/2009/03/30/changes-in-vml-for-ie8-or-what-feature-can-the-ie-dev-team-break-for-you-today/
- // but someone commented saying they didn't need it, and it seems jsPlumb doesnt need it either.
- // var iev = document.documentMode;
- //if (!iev || iev < 8)
- document.namespaces.add("jsplumb", "urn:schemas-microsoft-com:vml");
- //else
- // document.namespaces.add("jsplumb", "urn:schemas-microsoft-com:vml", "#default#VML");
- }
-
- var scale = 1000,
- _atts = function(o, atts) {
- for (var i in atts) {
- // IE8 fix: setattribute does not work after an element has been added to the dom!
- // http://www.louisremi.com/2009/03/30/changes-in-vml-for-ie8-or-what-feature-can-the-ie-dev-team-break-for-you-today/
- //o.setAttribute(i, atts[i]);
- o[i] = atts[i];
- }
- },
- _node = function(name, d, atts) {
- atts = atts || {};
- var o = document.createElement("jsplumb:" + name);
- o.className = (atts["class"] ? atts["class"] + " " : "") + "jsplumb_vml";
- _pos(o, d);
- _atts(o, atts);
- return o;
- },
- _pos = function(o,d) {
- o.style.left = d[0] + "px";
- o.style.top = d[1] + "px";
- o.style.width= d[2] + "px";
- o.style.height= d[3] + "px";
- o.style.position = "absolute";
- },
- _conv = function(v) {
- return Math.floor(v * scale);
- },
- _convertStyle = function(s, ignoreAlpha) {
- var o = s,
- pad = function(n) { return n.length == 1 ? "0" + n : n; },
- hex = function(k) { return pad(Number(k).toString(16)); },
- pattern = /(rgb[a]?\()(.*)(\))/;
- if (s.match(pattern)) {
- var parts = s.match(pattern)[2].split(",");
- o = "#" + hex(parts[0]) + hex(parts[1]) + hex(parts[2]);
- if (!ignoreAlpha && parts.length == 4)
- o = o + hex(parts[3]);
- }
-
- return o;
- },
- _applyStyles = function(node, style, component) {
- var styleToWrite = {};
- if (style.strokeStyle) {
- styleToWrite["stroked"] = "true";
- styleToWrite["strokecolor"] =_convertStyle(style.strokeStyle, true);
- styleToWrite["strokeweight"] = style.lineWidth + "px";
- }
- else styleToWrite["stroked"] = "false";
-
- if (style.fillStyle) {
- styleToWrite["filled"] = "true";
- styleToWrite["fillcolor"] = _convertStyle(style.fillStyle, true);
- }
- else styleToWrite["filled"] = "false";
-
- if(style["dashstyle"]) {
- if (component.strokeNode == null) {
- component.strokeNode = _node("stroke", [0,0,0,0], { dashstyle:style["dashstyle"] });
- node.appendChild(component.strokeNode);
- }
- else
- component.strokeNode.dashstyle = style["dashstyle"];
- }
- else if (style["stroke-dasharray"] && style["lineWidth"]) {
- var sep = style["stroke-dasharray"].indexOf(",") == -1 ? " " : ",",
- parts = style["stroke-dasharray"].split(sep),
- styleToUse = "";
- for(var i = 0; i < parts.length; i++) {
- styleToUse += (Math.floor(parts[i] / style.lineWidth) + sep);
- }
- if (component.strokeNode == null) {
- component.strokeNode = _node("stroke", [0,0,0,0], { dashstyle:styleToUse });
- node.appendChild(component.strokeNode);
- }
- else
- component.strokeNode.dashstyle = styleToUse;
- }
-
- _atts(node, styleToWrite);
- },
- /*
- * Base class for Vml endpoints and connectors. Extends jsPlumbUIComponent.
- */
- VmlComponent = function() {
- jsPlumb.jsPlumbUIComponent.apply(this, arguments);
- },
- /*
- * Base class for Vml connectors. extends VmlComponent.
- */
- VmlConnector = function(params) {
- var self = this;
- self.strokeNode = null;
- self.canvas = null;
- VmlComponent.apply(this, arguments);
- clazz = self._jsPlumb.connectorClass + (params.cssClass ? (" " + params.cssClass) : "");
- this.paint = function(d, style, anchor) {
- if (style != null) {
- var path = self.getPath(d), p = { "path":path };
-
- if (style.outlineColor) {
- var outlineWidth = style.outlineWidth || 1,
- outlineStrokeWidth = style.lineWidth + (2 * outlineWidth);
- outlineStyle = {
- strokeStyle:_convertStyle(style.outlineColor),
- lineWidth:outlineStrokeWidth
- };
-
- if (self.bgCanvas == null) {
- p["class"] = clazz;
- self.bgCanvas = _node("shape", d, p);
- jsPlumb.appendElement(self.bgCanvas, params.parent);
- displayElements.push(self.bgCanvas);
- }
- else {
- p["coordsize"] = (d[2] * scale) + "," + (d[3] * scale);
- _pos(self.bgCanvas, d);
- _atts(self.bgCanvas, p);
- }
-
- _applyStyles(self.bgCanvas, outlineStyle, self);
- }
-
- if (self.canvas == null) {
- p["class"] = clazz;
- self.canvas = _node("shape", d, p);
- jsPlumb.appendElement(self.canvas, params.parent);
- displayElements.push(self.canvas);
-
- self.attachListeners(self.canvas, self);
- }
- else {
- p["coordsize"] = (d[2] * scale) + "," + (d[3] * scale);
- _pos(self.canvas, d);
- _atts(self.canvas, p);
- }
-
- _applyStyles(self.canvas, style, self);
- }
- };
-
- var displayElements = [ self.canvas ];
- this.getDisplayElements = function() {
- return displayElements;
- };
-
- this.appendDisplayElement = function(el) {
- self.canvas.parentNode.appendChild(el);
- displayElements.push(el);
- };
- },
- /*
- *
- * Base class for Vml Endpoints. extends VmlComponent.
- *
- */
- VmlEndpoint = function(params) {
- VmlComponent.apply(this, arguments);
- var vml = null, self = this;
- self.canvas = document.createElement("div");
- self.canvas.style["position"] = "absolute";
- jsPlumb.appendElement(self.canvas, params.parent);
-
- this.paint = function(d, style, anchor) {
- var p = { };
-
- jsPlumb.sizeCanvas(self.canvas, d[0], d[1], d[2], d[3]);
- if (vml == null) {
- p["class"] = jsPlumb.endpointClass;
- vml = self.getVml([0,0, d[2], d[3]], p, anchor);
- self.canvas.appendChild(vml);
- self.attachListeners(vml, self);
- }
- else {
- //p["coordsize"] = "1,1";//(d[2] * scale) + "," + (d[3] * scale); again, unsure.
- _pos(vml, [0,0, d[2], d[3]]);
- _atts(vml, p);
- }
-
- _applyStyles(vml, style);
- };
- };
-
- jsPlumb.Connectors.vml.Bezier = function() {
- jsPlumb.Connectors.Bezier.apply(this, arguments);
- VmlConnector.apply(this, arguments);
- this.getPath = function(d) {
- return "m" + _conv(d[4]) + "," + _conv(d[5]) +
- " c" + _conv(d[8]) + "," + _conv(d[9]) + "," + _conv(d[10]) + "," + _conv(d[11]) + "," + _conv(d[6]) + "," + _conv(d[7]) + " e";
- };
- };
-
- jsPlumb.Connectors.vml.Straight = function() {
- jsPlumb.Connectors.Straight.apply(this, arguments);
- VmlConnector.apply(this, arguments);
- this.getPath = function(d) {
- return "m" + _conv(d[4]) + "," + _conv(d[5]) + " l" + _conv(d[6]) + "," + _conv(d[7]) + " e";
- };
- };
-
- jsPlumb.Connectors.vml.Flowchart = function() {
- jsPlumb.Connectors.Flowchart.apply(this, arguments);
- VmlConnector.apply(this, arguments);
- this.getPath = function(dimensions) {
- var p = "m " + _conv(dimensions[4]) + "," + _conv(dimensions[5]) + " l";
- // loop through extra points
- for (var i = 0; i < dimensions[8]; i++) {
- p = p + " " + _conv(dimensions[9 + (i*2)]) + "," + _conv(dimensions[10 + (i*2)]);
- }
- // finally draw a line to the end
- p = p + " " + _conv(dimensions[6]) + "," + _conv(dimensions[7]) + " e";
- return p;
- };
- };
-
- jsPlumb.Endpoints.vml.Dot = function() {
- jsPlumb.Endpoints.Dot.apply(this, arguments);
- VmlEndpoint.apply(this, arguments);
- this.getVml = function(d, atts, anchor) { return _node("oval", d, atts); };
- };
-
- jsPlumb.Endpoints.vml.Rectangle = function() {
- jsPlumb.Endpoints.Rectangle.apply(this, arguments);
- VmlEndpoint.apply(this, arguments);
- this.getVml = function(d, atts, anchor) { return _node("rect", d, atts); };
- };
-
- /*
- * VML Image Endpoint is the same as the default image endpoint.
- */
- jsPlumb.Endpoints.vml.Image = jsPlumb.Endpoints.Image;
-
- /**
- * placeholder for Blank endpoint in vml renderer.
- */
- jsPlumb.Endpoints.vml.Blank = jsPlumb.Endpoints.Blank;
-
- /**
- * VML Label renderer. uses the default label renderer (which adds an element to the DOM)
- */
- jsPlumb.Overlays.vml.Label = jsPlumb.Overlays.Label;
-
- var AbstractVmlArrowOverlay = function(superclass, originalArgs) {
- superclass.apply(this, originalArgs);
- VmlComponent.apply(this, arguments);
- var self = this, canvas = null, path =null;
- var getPath = function(d, connectorDimensions) {
- return "m " + _conv(d.hxy.x) + "," + _conv(d.hxy.y) +
- " l " + _conv(d.tail[0].x) + "," + _conv(d.tail[0].y) +
- " " + _conv(d.cxy.x) + "," + _conv(d.cxy.y) +
- " " + _conv(d.tail[1].x) + "," + _conv(d.tail[1].y) +
- " x e";
- };
- this.paint = function(connector, d, lineWidth, strokeStyle, fillStyle, connectorDimensions) {
- var p = {};
- if (strokeStyle) {
- p["stroked"] = "true";
- p["strokecolor"] =_convertStyle(strokeStyle, true);
- }
- if (lineWidth) p["strokeweight"] = lineWidth + "px";
- if (fillStyle) {
- p["filled"] = "true";
- p["fillcolor"] = fillStyle;
- }
- var xmin = Math.min(d.hxy.x, d.tail[0].x, d.tail[1].x, d.cxy.x),
- ymin = Math.min(d.hxy.y, d.tail[0].y, d.tail[1].y, d.cxy.y),
- xmax = Math.max(d.hxy.x, d.tail[0].x, d.tail[1].x, d.cxy.x),
- ymax = Math.max(d.hxy.y, d.tail[0].y, d.tail[1].y, d.cxy.y),
- w = Math.abs(xmax - xmin),
- h = Math.abs(ymax - ymin),
- dim = [xmin, ymin, w, h];
-
- // for VML, we create overlays using shapes that have the same dimensions and
- // coordsize as their connector - overlays calculate themselves relative to the
- // connector (it's how it's been done since the original canvas implementation, because
- // for canvas that makes sense).
- p["path"] = getPath(d, connectorDimensions);
- p["coordsize"] = (connectorDimensions[2] * scale) + "," + (connectorDimensions[3] * scale);
-
- dim[0] = connectorDimensions[0];
- dim[1] = connectorDimensions[1];
- dim[2] = connectorDimensions[2];
- dim[3] = connectorDimensions[3];
-
- if (canvas == null) {
- //p["class"] = jsPlumb.overlayClass; // TODO currentInstance?
- canvas = _node("shape", dim, p);
- connector.appendDisplayElement(canvas);
- self.attachListeners(canvas, connector);
- }
- else {
- _pos(canvas, dim);
- _atts(canvas, p);
- }
- };
- };
-
- jsPlumb.Overlays.vml.Arrow = function() {
- AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.Arrow, arguments]);
- };
-
- jsPlumb.Overlays.vml.PlainArrow = function() {
- AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.PlainArrow, arguments]);
- };
-
- jsPlumb.Overlays.vml.Diamond = function() {
- AbstractVmlArrowOverlay.apply(this, [jsPlumb.Overlays.Diamond, arguments]);
- };
- })();
|