diff options
author | adhitya | 2016-04-10 12:28:28 +0000 |
---|---|---|
committer | adhitya | 2016-04-10 12:28:28 +0000 |
commit | 0b1c069f88dab0288a01c6aed4d77f4e6d2f6474 (patch) | |
tree | b5ae6b1f512a674f79674a12f675d22324cd268f /src/js/shape | |
parent | 1993f1da86e293aaf9996b8d7a4f6d9a9224f270 (diff) | |
download | xcos-on-web-0b1c069f88dab0288a01c6aed4d77f4e6d2f6474.tar.gz xcos-on-web-0b1c069f88dab0288a01c6aed4d77f4e6d2f6474.tar.bz2 xcos-on-web-0b1c069f88dab0288a01c6aed4d77f4e6d2f6474.zip |
Removed (un)necessary files
Diffstat (limited to 'src/js/shape')
-rw-r--r-- | src/js/shape/mxActor.js | 183 | ||||
-rw-r--r-- | src/js/shape/mxArrow.js | 226 | ||||
-rw-r--r-- | src/js/shape/mxCloud.js | 56 | ||||
-rw-r--r-- | src/js/shape/mxConnector.js | 446 | ||||
-rw-r--r-- | src/js/shape/mxCylinder.js | 319 | ||||
-rw-r--r-- | src/js/shape/mxDoubleEllipse.js | 203 | ||||
-rw-r--r-- | src/js/shape/mxEllipse.js | 132 | ||||
-rw-r--r-- | src/js/shape/mxHexagon.js | 37 | ||||
-rw-r--r-- | src/js/shape/mxImageShape.js | 405 | ||||
-rw-r--r-- | src/js/shape/mxLabel.js | 427 | ||||
-rw-r--r-- | src/js/shape/mxLine.js | 217 | ||||
-rw-r--r-- | src/js/shape/mxMarker.js | 267 | ||||
-rw-r--r-- | src/js/shape/mxPolyline.js | 146 | ||||
-rw-r--r-- | src/js/shape/mxRectangleShape.js | 61 | ||||
-rw-r--r-- | src/js/shape/mxRhombus.js | 172 | ||||
-rw-r--r-- | src/js/shape/mxShape.js | 2045 | ||||
-rw-r--r-- | src/js/shape/mxStencil.js | 1585 | ||||
-rw-r--r-- | src/js/shape/mxStencilRegistry.js | 53 | ||||
-rw-r--r-- | src/js/shape/mxStencilShape.js | 209 | ||||
-rw-r--r-- | src/js/shape/mxSwimlane.js | 553 | ||||
-rw-r--r-- | src/js/shape/mxText.js | 1811 | ||||
-rw-r--r-- | src/js/shape/mxTriangle.js | 34 |
22 files changed, 0 insertions, 9587 deletions
diff --git a/src/js/shape/mxActor.js b/src/js/shape/mxActor.js deleted file mode 100644 index e6a0765..0000000 --- a/src/js/shape/mxActor.js +++ /dev/null @@ -1,183 +0,0 @@ -/** - * $Id: mxActor.js,v 1.35 2012-07-31 11:46:53 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxActor - * - * Extends <mxShape> to implement an actor shape. If a custom shape with one - * filled area is needed, then this shape's <redrawPath> should be overridden. - * - * Example: - * - * (code) - * function SampleShape() { } - * - * SampleShape.prototype = new mxActor(); - * SampleShape.prototype.constructor = vsAseShape; - * - * mxCellRenderer.prototype.defaultShapes['sample'] = SampleShape; - * SampleShape.prototype.redrawPath = function(path, x, y, w, h) - * { - * path.moveTo(0, 0); - * path.lineTo(w, h); - * // ... - * path.close(); - * } - * (end) - * - * This shape is registered under <mxConstants.SHAPE_ACTOR> in - * <mxCellRenderer>. - * - * Constructor: mxActor - * - * Constructs a new actor shape. - * - * Parameters: - * - * bounds - <mxRectangle> that defines the bounds. This is stored in - * <mxShape.bounds>. - * fill - String that defines the fill color. This is stored in <fill>. - * stroke - String that defines the stroke color. This is stored in <stroke>. - * strokewidth - Optional integer that defines the stroke width. Default is - * 1. This is stored in <strokewidth>. - */ -function mxActor(bounds, fill, stroke, strokewidth) -{ - this.bounds = bounds; - this.fill = fill; - this.stroke = stroke; - this.strokewidth = (strokewidth != null) ? strokewidth : 1; -}; - -/** - * Extends mxShape. - */ -mxActor.prototype = new mxShape(); -mxActor.prototype.constructor = mxActor; - -/** - * Variable: mixedModeHtml - * - * Overrides the parent value with false, meaning it will - * draw in VML in mixed Html mode. - */ -mxActor.prototype.mixedModeHtml = false; - -/** - * Variable: preferModeHtml - * - * Overrides the parent value with false, meaning it will - * draw as VML in prefer Html mode. - */ -mxActor.prototype.preferModeHtml = false; - -/** - * Variable: vmlScale - * - * Renders VML with a scale of 2. - */ -mxActor.prototype.vmlScale = 2; - -/** - * Function: createVml - * - * Creates and returns the VML node(s) to represent this shape. - */ -mxActor.prototype.createVml = function() -{ - var node = document.createElement('v:shape'); - node.style.position = 'absolute'; - this.configureVmlShape(node); - - return node; -}; - -/** - * Function: redrawVml - * - * Updates the VML node(s) to reflect the latest bounds and scale. - */ -mxActor.prototype.redrawVml = function() -{ - this.updateVmlShape(this.node); - this.node.path = this.createPath(); -}; - -/** - * Function: createSvg - * - * Creates and returns the SVG node(s) to represent this shape. - */ -mxActor.prototype.createSvg = function() -{ - return this.createSvgGroup('path'); -}; - -/** - * Function: redrawSvg - * - * Updates the SVG node(s) to reflect the latest bounds and scale. - */ -mxActor.prototype.redrawSvg = function() -{ - var strokeWidth = Math.round(Math.max(1, this.strokewidth * this.scale)); - this.innerNode.setAttribute('stroke-width', strokeWidth); - this.innerNode.setAttribute('stroke-linejoin', 'round'); - - if (this.crisp && (this.rotation == null || this.rotation == 0)) - { - this.innerNode.setAttribute('shape-rendering', 'crispEdges'); - } - else - { - this.innerNode.removeAttribute('shape-rendering'); - } - - var d = this.createPath(); - - if (d.length > 0) - { - this.innerNode.setAttribute('d', d); - - if (this.shadowNode != null) - { - this.shadowNode.setAttribute('transform', this.getSvgShadowTransform() + - (this.innerNode.getAttribute('transform') || '')); - this.shadowNode.setAttribute('stroke-width', strokeWidth); - this.shadowNode.setAttribute('d', d); - } - } - else - { - this.innerNode.removeAttribute('d'); - - if (this.shadowNode != null) - { - this.shadowNode.removeAttribute('d'); - } - } - - if (this.isDashed) - { - var phase = Math.max(1, Math.round(3 * this.scale * this.strokewidth)); - this.innerNode.setAttribute('stroke-dasharray', phase + ' ' + phase); - } -}; - -/** - * Function: redrawPath - * - * Draws the path for this shape. This method uses the <mxPath> - * abstraction to paint the shape for VML and SVG. - */ -mxActor.prototype.redrawPath = function(path, x, y, w, h) -{ - var width = w/3; - path.moveTo(0, h); - path.curveTo(0, 3 * h / 5, 0, 2 * h / 5, w / 2, 2 * h / 5); - path.curveTo(w / 2 - width, 2 * h / 5, w / 2 - width, 0, w / 2, 0); - path.curveTo(w / 2 + width, 0, w / 2 + width, 2 * h / 5, w / 2, 2 * h / 5); - path.curveTo(w, 2 * h / 5, w, 3 * h / 5, w, h); - path.close(); -}; diff --git a/src/js/shape/mxArrow.js b/src/js/shape/mxArrow.js deleted file mode 100644 index 93777d8..0000000 --- a/src/js/shape/mxArrow.js +++ /dev/null @@ -1,226 +0,0 @@ -/** - * $Id: mxArrow.js,v 1.31 2012-05-23 19:09:22 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxArrow - * - * Extends <mxShape> to implement an arrow shape. (The shape - * is used to represent edges, not vertices.) - * This shape is registered under <mxConstants.SHAPE_ARROW> - * in <mxCellRenderer>. - * - * Constructor: mxArrow - * - * Constructs a new arrow shape. - * - * Parameters: - * - * points - Array of <mxPoints> that define the points. This is stored in - * <mxShape.points>. - * fill - String that defines the fill color. This is stored in <fill>. - * stroke - String that defines the stroke color. This is stored in <stroke>. - * strokewidth - Optional integer that defines the stroke width. Default is - * 1. This is stored in <strokewidth>. - * arrowWidth - Optional integer that defines the arrow width. Default is - * <mxConstants.ARROW_WIDTH>. This is stored in <arrowWidth>. - * spacing - Optional integer that defines the spacing between the arrow shape - * and its endpoints. Default is <mxConstants.ARROW_SPACING>. This is stored in - * <spacing>. - * endSize - Optional integer that defines the size of the arrowhead. Default - * is <mxConstants.ARROW_SIZE>. This is stored in <endSize>. - */ -function mxArrow(points, fill, stroke, strokewidth, arrowWidth, spacing, endSize) -{ - this.points = points; - this.fill = fill; - this.stroke = stroke; - this.strokewidth = (strokewidth != null) ? strokewidth : 1; - this.arrowWidth = (arrowWidth != null) ? arrowWidth : mxConstants.ARROW_WIDTH; - this.spacing = (spacing != null) ? spacing : mxConstants.ARROW_SPACING; - this.endSize = (endSize != null) ? endSize : mxConstants.ARROW_SIZE; -}; - -/** - * Extends <mxActor>. - */ -mxArrow.prototype = new mxActor(); -mxArrow.prototype.constructor = mxArrow; - -/** - * Variable: addPipe - * - * Specifies if a SVG path should be created around any path to increase the - * tolerance for mouse events. Default is false since this shape is filled. - */ -mxArrow.prototype.addPipe = false; - -/** - * Variable: enableFill - * - * Specifies if fill colors should be ignored. This must be set to true for - * shapes that are stroked only. Default is true since this shape is filled. - */ -mxArrow.prototype.enableFill = true; - -/** - * Function: configureTransparentBackground - * - * Overidden to remove transparent background. - */ -mxArrow.prototype.configureTransparentBackground = function(node) -{ - // do nothing -}; - -/** - * Function: updateBoundingBox - * - * Updates the <boundingBox> for this shape. - */ -mxArrow.prototype.augmentBoundingBox = function(bbox) -{ - // FIXME: Fix precision, share math and cache results with painting code - bbox.grow(Math.max(this.arrowWidth / 2, this.endSize / 2) * this.scale); - - mxShape.prototype.augmentBoundingBox.apply(this, arguments); -}; - -/** - * Function: createVml - * - * Extends <mxShape.createVml> to ignore fill if <enableFill> is false. - */ -mxArrow.prototype.createVml = function() -{ - if (!this.enableFill) - { - this.fill = null; - } - - return mxActor.prototype.createVml.apply(this, arguments); -}; - -/** - * Function: createSvg - * - * Extends <mxActor.createSvg> to ignore fill if <enableFill> is false and - * create an event handling shape if <this.addPipe> is true. - */ -mxArrow.prototype.createSvg = function() -{ - if (!this.enableFill) - { - this.fill = null; - } - - var g = mxActor.prototype.createSvg.apply(this, arguments); - - // Creates an invisible shape around the path for easier - // selection with the mouse. Note: Firefox does not ignore - // the value of the stroke attribute for pointer-events: stroke, - // it does, however, ignore the visibility attribute. - if (this.addPipe) - { - this.pipe = this.createSvgPipe(); - g.appendChild(this.pipe); - } - - return g; -}; - -/** - * Function: reconfigure - * - * Extends <mxActor.reconfigure> to ignore fill if <enableFill> is false. - */ -mxArrow.prototype.reconfigure = function() -{ - if (!this.enableFill) - { - this.fill = null; - } - - mxActor.prototype.reconfigure.apply(this, arguments); -}; - -/** - * Function: redrawSvg - * - * Extends <mxActor.redrawSvg> to update the event handling shape if one - * exists. - */ -mxArrow.prototype.redrawSvg = function() -{ - mxActor.prototype.redrawSvg.apply(this, arguments); - - if (this.pipe != null) - { - var d = this.innerNode.getAttribute('d'); - - if (d != null) - { - this.pipe.setAttribute('d', this.innerNode.getAttribute('d')); - var strokeWidth = Math.round(this.strokewidth * this.scale); - this.pipe.setAttribute('stroke-width', strokeWidth + mxShape.prototype.SVG_STROKE_TOLERANCE); - } - } -}; - -/** - * Function: redrawPath - * - * Draws the path for this shape. This method uses the <mxPath> - * abstraction to paint the shape for VML and SVG. - */ -mxArrow.prototype.redrawPath = function(path, x, y, w, h) -{ - // All points are offset - path.translate.x -= x; - path.translate.y -= y; - - // Geometry of arrow - var spacing = this.spacing * this.scale; - var width = this.arrowWidth * this.scale; - var arrow = this.endSize * this.scale; - - // Base vector (between end points) - var p0 = this.points[0]; - var pe = this.points[this.points.length - 1]; - - var dx = pe.x - p0.x; - var dy = pe.y - p0.y; - var dist = Math.sqrt(dx * dx + dy * dy); - var length = dist - 2 * spacing - arrow; - - // Computes the norm and the inverse norm - var nx = dx / dist; - var ny = dy / dist; - var basex = length * nx; - var basey = length * ny; - var floorx = width * ny/3; - var floory = -width * nx/3; - - // Computes points - var p0x = p0.x - floorx / 2 + spacing * nx; - var p0y = p0.y - floory / 2 + spacing * ny; - var p1x = p0x + floorx; - var p1y = p0y + floory; - var p2x = p1x + basex; - var p2y = p1y + basey; - var p3x = p2x + floorx; - var p3y = p2y + floory; - // p4 not necessary - var p5x = p3x - 3 * floorx; - var p5y = p3y - 3 * floory; - - path.moveTo(p0x, p0y); - path.lineTo(p1x, p1y); - path.lineTo(p2x, p2y); - path.lineTo(p3x, p3y); - path.lineTo(pe.x - spacing * nx, pe.y - spacing * ny); - path.lineTo(p5x, p5y); - path.lineTo(p5x + floorx, p5y + floory); - path.lineTo(p0x, p0y); - path.close(); -}; diff --git a/src/js/shape/mxCloud.js b/src/js/shape/mxCloud.js deleted file mode 100644 index 3893a1b..0000000 --- a/src/js/shape/mxCloud.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * $Id: mxCloud.js,v 1.12 2011-06-24 11:27:30 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxCloud - * - * Extends <mxActor> to implement a cloud shape. - * - * This shape is registered under <mxConstants.SHAPE_CLOUD> in - * <mxCellRenderer>. - * - * Constructor: mxCloud - * - * Constructs a new cloud shape. - * - * Parameters: - * - * bounds - <mxRectangle> that defines the bounds. This is stored in - * <mxShape.bounds>. - * fill - String that defines the fill color. This is stored in <fill>. - * stroke - String that defines the stroke color. This is stored in <stroke>. - * strokewidth - Optional integer that defines the stroke width. Default is - * 1. This is stored in <strokewidth>. - */ -function mxCloud(bounds, fill, stroke, strokewidth) -{ - this.bounds = bounds; - this.fill = fill; - this.stroke = stroke; - this.strokewidth = (strokewidth != null) ? strokewidth : 1; -}; - -/** - * Extends mxActor. - */ -mxCloud.prototype = new mxActor(); -mxCloud.prototype.constructor = mxActor; - -/** - * Function: redrawPath - * - * Draws the path for this shape. This method uses the <mxPath> - * abstraction to paint the shape for VML and SVG. - */ -mxCloud.prototype.redrawPath = function(path, x, y, w, h) -{ - path.moveTo(0.25 * w, 0.25 * h); - path.curveTo(0.05 * w, 0.25 * h, 0, 0.5 * h, 0.16 * w, 0.55 * h); - path.curveTo(0, 0.66 * h, 0.18 * w, 0.9 * h, 0.31 * w, 0.8 * h); - path.curveTo(0.4 * w, h, 0.7 * w, h, 0.8 * w, 0.8 * h); - path.curveTo(w, 0.8 * h, w, 0.6 * h, 0.875 * w, 0.5 * h); - path.curveTo(w, 0.3 * h, 0.8 * w, 0.1 * h, 0.625 * w, 0.2 * h); - path.curveTo(0.5 * w, 0.05 * h, 0.3 * w, 0.05 * h, 0.25 * w, 0.25 * h); - path.close(); -}; diff --git a/src/js/shape/mxConnector.js b/src/js/shape/mxConnector.js deleted file mode 100644 index 092bf79..0000000 --- a/src/js/shape/mxConnector.js +++ /dev/null @@ -1,446 +0,0 @@ -/** - * $Id: mxConnector.js,v 1.80 2012-05-24 12:00:45 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxConnector - * - * Extends <mxShape> to implement a connector shape. The connector - * shape allows for arrow heads on either side. - * - * This shape is registered under <mxConstants.SHAPE_CONNECTOR> in - * <mxCellRenderer>. - * - * Constructor: mxConnector - * - * Constructs a new connector shape. - * - * Parameters: - * - * points - Array of <mxPoints> that define the points. This is stored in - * <mxShape.points>. - * stroke - String that defines the stroke color. This is stored in <stroke>. - * Default is 'black'. - * strokewidth - Optional integer that defines the stroke width. Default is - * 1. This is stored in <strokewidth>. - */ -function mxConnector(points, stroke, strokewidth) -{ - this.points = points; - this.stroke = stroke; - this.strokewidth = (strokewidth != null) ? strokewidth : 1; -}; - -/** - * Extends mxShape. - */ -mxConnector.prototype = new mxShape(); -mxConnector.prototype.constructor = mxConnector; - -/** - * Variable: vmlNodes - * - * Adds local references to <mxShape.vmlNodes>. - */ -mxConnector.prototype.vmlNodes = mxConnector.prototype.vmlNodes.concat([ - 'shapeNode', 'start', 'end', 'startStroke', 'endStroke', 'startFill', 'endFill']); - -/** - * Variable: mixedModeHtml - * - * Overrides the parent value with false, meaning it will - * draw in VML in mixed Html mode. - */ -mxConnector.prototype.mixedModeHtml = false; - -/** - * Variable: preferModeHtml - * - * Overrides the parent value with false, meaning it will - * draw as VML in prefer Html mode. - */ -mxConnector.prototype.preferModeHtml = false; - -/** - * Variable: allowCrispMarkers - * - * Specifies if <mxShape.crisp> should be allowed for markers. Default is false. - */ -mxConnector.prototype.allowCrispMarkers = false; - -/** - * Variable: addPipe - * - * Specifies if a SVG path should be created around any path to increase the - * tolerance for mouse events. Default is false since this shape is filled. - */ -mxConnector.prototype.addPipe = true; - -/** - * Function: configureHtmlShape - * - * Overrides <mxShape.configureHtmlShape> to clear the border and background. - */ -mxConnector.prototype.configureHtmlShape = function(node) -{ - mxShape.prototype.configureHtmlShape.apply(this, arguments); - node.style.borderStyle = ''; - node.style.background = ''; -}; - -/** - * Function: createVml - * - * Creates and returns the VML node to represent this shape. - */ -mxConnector.prototype.createVml = function() -{ - var node = document.createElement('v:group'); - node.style.position = 'absolute'; - this.shapeNode = document.createElement('v:shape'); - this.updateVmlStrokeColor(this.shapeNode); - this.updateVmlStrokeNode(this.shapeNode); - node.appendChild(this.shapeNode); - this.shapeNode.filled = 'false'; - - if (this.isShadow) - { - this.createVmlShadow(this.shapeNode); - } - - // Creates the start arrow as an additional child path - if (this.startArrow != null) - { - this.start = document.createElement('v:shape'); - this.start.style.position = 'absolute'; - - // Only required for opacity and joinstyle - this.startStroke = document.createElement('v:stroke'); - this.startStroke.joinstyle = 'miter'; - this.start.appendChild(this.startStroke); - - this.startFill = document.createElement('v:fill'); - this.start.appendChild(this.startFill); - - node.appendChild(this.start); - } - - // Creates the end arrows as an additional child path - if (this.endArrow != null) - { - this.end = document.createElement('v:shape'); - this.end.style.position = 'absolute'; - - // Only required for opacity and joinstyle - this.endStroke = document.createElement('v:stroke'); - this.endStroke.joinstyle = 'miter'; - this.end.appendChild(this.endStroke); - - this.endFill = document.createElement('v:fill'); - this.end.appendChild(this.endFill); - - node.appendChild(this.end); - } - - this.updateVmlMarkerOpacity(); - - return node; -}; - -/** - * Function: updateVmlMarkerOpacity - * - * Updates the opacity for the markers in VML. - */ -mxConnector.prototype.updateVmlMarkerOpacity = function() -{ - var op = (this.opacity != null) ? (this.opacity + '%') : '100%'; - - if (this.start != null) - { - this.startFill.opacity = op; - this.startStroke.opacity = op; - } - - if (this.end != null) - { - this.endFill.opacity = op; - this.endStroke.opacity = op; - } -}; - -/** - * Function: redrawVml - * - * Redraws this VML shape by invoking <updateVmlShape> on this.node. - */ -mxConnector.prototype.reconfigure = function() -{ - // Never fill a connector - this.fill = null; - - if (mxUtils.isVml(this.node)) - { - // Updates the style of the given shape - // LATER: Check if this can be replaced with redrawVml and - // updating the color, dash pattern and shadow. - this.node.style.visibility = 'hidden'; - this.configureVmlShape(this.shapeNode); - this.updateVmlMarkerOpacity(); - this.node.style.visibility = 'visible'; - } - else - { - mxShape.prototype.reconfigure.apply(this, arguments); - } -}; - -/** - * Function: redrawVml - * - * Redraws this VML shape by invoking <updateVmlShape> on this.node. - */ -mxConnector.prototype.redrawVml = function() -{ - if (this.node != null && this.points != null && this.bounds != null && - !isNaN(this.bounds.x) && !isNaN(this.bounds.y) && - !isNaN(this.bounds.width) && !isNaN(this.bounds.height)) - { - var w = Math.max(0, Math.round(this.bounds.width)); - var h = Math.max(0, Math.round(this.bounds.height)); - var cs = w + ',' + h; - w += 'px'; - h += 'px'; - - // Computes the marker paths before the main path is updated so - // that offsets can be taken into account - if (this.start != null) - { - this.start.style.width = w; - this.start.style.height = h; - this.start.coordsize = cs; - - var p0 = this.points[1]; - var pe = this.points[0]; - - var size = mxUtils.getNumber(this.style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_MARKERSIZE); - this.startOffset = this.redrawMarker(this.start, this.startArrow, p0, pe, this.stroke, size); - } - - if (this.end != null) - { - this.end.style.width = w; - this.end.style.height = h; - this.end.coordsize = cs; - - var n = this.points.length; - var p0 = this.points[n - 2]; - var pe = this.points[n - 1]; - - var size = mxUtils.getNumber(this.style, mxConstants.STYLE_ENDSIZE, mxConstants.DEFAULT_MARKERSIZE); - this.endOffset = this.redrawMarker(this.end, this.endArrow, p0, pe, this.stroke, size); - } - - this.updateVmlShape(this.node); - this.updateVmlShape(this.shapeNode); - this.shapeNode.filled = 'false'; - - // Adds custom dash pattern - if (this.isDashed) - { - var pat = mxUtils.getValue(this.style, 'dashStyle', null); - - if (pat != null) - { - this.strokeNode.dashstyle = pat; - } - - if (this.shadowStrokeNode != null) - { - this.shadowStrokeNode.dashstyle = this.strokeNode.dashstyle; - } - } - } -}; - -/** - * Function: createSvg - * - * Creates and returns the SVG node to represent this shape. - */ -mxConnector.prototype.createSvg = function() -{ - this.fill = null; - var g = this.createSvgGroup('path'); - - // Creates the start arrow as an additional child path - if (this.startArrow != null) - { - this.start = document.createElementNS(mxConstants.NS_SVG, 'path'); - g.appendChild(this.start); - } - - // Creates the end arrows as an additional child path - if (this.endArrow != null) - { - this.end = document.createElementNS(mxConstants.NS_SVG, 'path'); - g.appendChild(this.end); - } - - // Creates an invisible shape around the path for easier - // selection with the mouse. Note: Firefox does not ignore - // the value of the stroke attribute for pointer-events: stroke, - // it does, however, ignore the visibility attribute. - if (this.addPipe) - { - this.pipe = this.createSvgPipe(); - g.appendChild(this.pipe); - } - - return g; -}; - -/** - * Function: redrawSvg - * - * Updates the SVG node(s) to reflect the latest bounds and scale. - */ -mxConnector.prototype.redrawSvg = function() -{ - // Computes the markers first which modifies the coordinates of the - // endpoints to not overlap with the painted marker then updates the actual - // shape for the edge to take the modified endpoints into account. - if (this.points != null && this.points[0] != null) - { - var color = this.innerNode.getAttribute('stroke'); - - // Draws the start marker - if (this.start != null) - { - var p0 = this.points[1]; - var pe = this.points[0]; - - var size = mxUtils.getNumber(this.style, mxConstants.STYLE_STARTSIZE, - mxConstants.DEFAULT_MARKERSIZE); - this.startOffset = this.redrawMarker(this.start, - this.startArrow, p0, pe, color, size); - - if (this.allowCrispMarkers && this.crisp) - { - this.start.setAttribute('shape-rendering', 'crispEdges'); - } - else - { - this.start.removeAttribute('shape-rendering'); - } - } - - // Draws the end marker - if (this.end != null) - { - var n = this.points.length; - - var p0 = this.points[n - 2]; - var pe = this.points[n - 1]; - - var size = mxUtils.getNumber(this.style, mxConstants.STYLE_ENDSIZE, - mxConstants.DEFAULT_MARKERSIZE); - this.endOffset = this.redrawMarker(this.end, - this.endArrow, p0, pe, color, size); - - if (this.allowCrispMarkers && this.crisp) - { - this.end.setAttribute('shape-rendering', 'crispEdges'); - } - else - { - this.end.removeAttribute('shape-rendering'); - } - } - } - - this.updateSvgShape(this.innerNode); - var d = this.innerNode.getAttribute('d'); - - if (d != null) - { - var strokeWidth = Math.round(this.strokewidth * this.scale); - - // Updates the tolerance of the invisible shape for event handling - if (this.pipe != null) - { - this.pipe.setAttribute('d', this.innerNode.getAttribute('d')); - this.pipe.setAttribute('stroke-width', strokeWidth + mxShape.prototype.SVG_STROKE_TOLERANCE); - } - - // Updates the shadow - if (this.shadowNode != null) - { - this.shadowNode.setAttribute('transform', this.getSvgShadowTransform()); - this.shadowNode.setAttribute('d', d); - this.shadowNode.setAttribute('stroke-width', strokeWidth); - } - } - - // Adds custom dash pattern - if (this.isDashed) - { - var pat = this.createDashPattern(this.scale * this.strokewidth); - - if (pat != null) - { - this.innerNode.setAttribute('stroke-dasharray', pat); - } - } - - // Updates the shadow - if (this.shadowNode != null) - { - var pat = this.innerNode.getAttribute('stroke-dasharray'); - - if (pat != null) - { - this.shadowNode.setAttribute('stroke-dasharray', pat); - } - } -}; - -/** - * Function: createDashPattern - * - * Creates a dash pattern for the given factor. - */ -mxConnector.prototype.createDashPattern = function(factor) -{ - var value = mxUtils.getValue(this.style, 'dashPattern', null); - - if (value != null) - { - var tmp = value.split(' '); - var pat = []; - - for (var i = 0; i < tmp.length; i++) - { - if (tmp[i].length > 0) - { - pat.push(Math.round(Number(tmp[i]) * factor)); - } - } - - return pat.join(' '); - } - - return null; -}; - -/** - * Function: redrawMarker - * - * Updates the given SVG or VML marker. - */ -mxConnector.prototype.redrawMarker = function(node, type, p0, pe, color, size) -{ - return mxMarker.paintMarker(node, type, p0, pe, color, this.strokewidth, - size, this.scale, this.bounds.x, this.bounds.y, this.start == node, - this.style); -}; diff --git a/src/js/shape/mxCylinder.js b/src/js/shape/mxCylinder.js deleted file mode 100644 index 9a45760..0000000 --- a/src/js/shape/mxCylinder.js +++ /dev/null @@ -1,319 +0,0 @@ -/** - * $Id: mxCylinder.js,v 1.38 2012-07-31 11:46:53 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxCylinder - * - * Extends <mxShape> to implement an cylinder shape. If a - * custom shape with one filled area and an overlay path is - * needed, then this shape's <redrawPath> should be overridden. - * This shape is registered under <mxConstants.SHAPE_CYLINDER> - * in <mxCellRenderer>. - * - * Constructor: mxCylinder - * - * Constructs a new cylinder shape. - * - * Parameters: - * - * bounds - <mxRectangle> that defines the bounds. This is stored in - * <mxShape.bounds>. - * fill - String that defines the fill color. This is stored in <fill>. - * stroke - String that defines the stroke color. This is stored in <stroke>. - * strokewidth - Optional integer that defines the stroke width. Default is - * 1. This is stored in <strokewidth>. - */ -function mxCylinder(bounds, fill, stroke, strokewidth) -{ - this.bounds = bounds; - this.fill = fill; - this.stroke = stroke; - this.strokewidth = (strokewidth != null) ? strokewidth : 1; -}; - -/** - * Extends mxShape. - */ -mxCylinder.prototype = new mxShape(); -mxCylinder.prototype.constructor = mxCylinder; - -/** - * Variable: vmlNodes - * - * Adds local references to <mxShape.vmlNodes>. - */ -mxCylinder.prototype.vmlNodes = mxCylinder.prototype.vmlNodes.concat(['background', 'foreground']); - -/** - * Variable: mixedModeHtml - * - * Overrides the parent value with false, meaning it will - * draw in VML in mixed Html mode. - */ -mxCylinder.prototype.mixedModeHtml = false; - -/** - * Variable: preferModeHtml - * - * Overrides the parent value with false, meaning it will - * draw as VML in prefer Html mode. - */ -mxCylinder.prototype.preferModeHtml = false; - -/** - * Variable: addPipe - * - * Specifies if a SVG path should be created around the background for better - * hit detection. Default is false. - */ -mxCylinder.prototype.addPipe = false; - -/** - * Variable: strokedBackground - * - * Specifies if the background should be stroked. Default is true. - */ -mxCylinder.prototype.strokedBackground = true; - -/** - * Variable: maxHeight - * - * Defines the maximum height of the top and bottom part - * of the cylinder shape. - */ -mxCylinder.prototype.maxHeight = 40; - -/** - * Variable: vmlScale - * - * Renders VML with a scale of 2. - */ -mxCylinder.prototype.vmlScale = 2; - -/** - * Function: create - * - * Overrides the method to make sure the <stroke> is never - * null. If it is null is will be assigned the <fill> color. - */ -mxCylinder.prototype.create = function(container) -{ - if (this.stroke == null) - { - this.stroke = this.fill; - } - - // Calls superclass implementation of create - return mxShape.prototype.create.apply(this, arguments); -}; - -/** - * Function: reconfigure - * - * Overrides the method to make sure the <stroke> is applied to the foreground. - */ -mxCylinder.prototype.reconfigure = function() -{ - if (this.dialect == mxConstants.DIALECT_SVG) - { - this.configureSvgShape(this.foreground); - this.foreground.setAttribute('fill', 'none'); - } - else if (mxUtils.isVml(this.node)) - { - this.configureVmlShape(this.background); - this.configureVmlShape(this.foreground); - } - - mxShape.prototype.reconfigure.apply(this); -}; - -/** - * Function: createVml - * - * Creates and returns the VML node to represent this shape. - */ -mxCylinder.prototype.createVml = function() -{ - var node = document.createElement('v:group'); - - // Draws the background - this.background = document.createElement('v:shape'); - this.label = this.background; - this.configureVmlShape(this.background); - node.appendChild(this.background); - - // Ignores values that only apply to the background - this.fill = null; - this.isShadow = false; - this.configureVmlShape(node); - - // Draws the foreground - this.foreground = document.createElement('v:shape'); - this.configureVmlShape(this.foreground); - - // To match SVG defaults jointsyle miter, miterlimit 4 - this.fgStrokeNode = document.createElement('v:stroke'); - this.fgStrokeNode.joinstyle = 'miter'; - this.fgStrokeNode.miterlimit = 4; - this.foreground.appendChild(this.fgStrokeNode); - - node.appendChild(this.foreground); - - return node; -}; - -/** - * Function: redrawVml - * - * Updates the VML node(s) to reflect the latest bounds and scale. - */ -mxCylinder.prototype.redrawVml = function() -{ - this.updateVmlShape(this.node); - this.updateVmlShape(this.background); - this.updateVmlShape(this.foreground); - this.background.path = this.createPath(false); - this.foreground.path = this.createPath(true); - - this.fgStrokeNode.dashstyle = this.strokeNode.dashstyle; -}; - -/** - * Function: createSvg - * - * Creates and returns the SVG node(s) to represent this shape. - */ -mxCylinder.prototype.createSvg = function() -{ - var g = this.createSvgGroup('path'); - this.foreground = document.createElementNS(mxConstants.NS_SVG, 'path'); - - if (this.stroke != null && this.stroke != mxConstants.NONE) - { - this.foreground.setAttribute('stroke', this.stroke); - } - else - { - this.foreground.setAttribute('stroke', 'none'); - } - - this.foreground.setAttribute('fill', 'none'); - g.appendChild(this.foreground); - - if (this.addPipe) - { - this.pipe = this.createSvgPipe(); - g.appendChild(this.pipe); - } - - return g; -}; - -/** - * Function: redrawSvg - * - * Updates the SVG node(s) to reflect the latest bounds and scale. - */ -mxCylinder.prototype.redrawSvg = function() -{ - var strokeWidth = Math.round(Math.max(1, this.strokewidth * this.scale)); - this.innerNode.setAttribute('stroke-width', strokeWidth); - - if (this.crisp && (this.rotation == null || this.rotation == 0)) - { - this.innerNode.setAttribute('shape-rendering', 'crispEdges'); - this.foreground.setAttribute('shape-rendering', 'crispEdges'); - } - else - { - this.innerNode.removeAttribute('shape-rendering'); - this.foreground.removeAttribute('shape-rendering'); - } - - // Paints background - var d = this.createPath(false); - - if (d.length > 0) - { - this.innerNode.setAttribute('d', d); - - // Updates event handling element - if (this.pipe != null) - { - this.pipe.setAttribute('d', d); - this.pipe.setAttribute('stroke-width', strokeWidth + mxShape.prototype.SVG_STROKE_TOLERANCE); - this.pipe.setAttribute('transform', (this.innerNode.getAttribute('transform') || '')); - } - } - else - { - this.innerNode.removeAttribute('d'); - - // Updates event handling element - if (this.pipe != null) - { - this.pipe.removeAttribute('d'); - } - } - - // Stroked background - if (!this.strokedBackground) - { - this.innerNode.setAttribute('stroke', 'none'); - } - - // Paints shadow - if (this.shadowNode != null) - { - this.shadowNode.setAttribute('stroke-width', strokeWidth); - this.shadowNode.setAttribute('d', d); - this.shadowNode.setAttribute('transform', this.getSvgShadowTransform()); - } - - // Paints foreground - d = this.createPath(true); - - if (d.length > 0) - { - this.foreground.setAttribute('stroke-width', strokeWidth); - this.foreground.setAttribute('d', d); - } - else - { - this.foreground.removeAttribute('d'); - } - - if (this.isDashed) - { - var phase = Math.max(1, Math.round(3 * this.scale * this.strokewidth)); - this.innerNode.setAttribute('stroke-dasharray', phase + ' ' + phase); - this.foreground.setAttribute('stroke-dasharray', phase + ' ' + phase); - } -}; - -/** - * Function: redrawPath - * - * Draws the path for this shape. This method uses the <mxPath> - * abstraction to paint the shape for VML and SVG. - */ -mxCylinder.prototype.redrawPath = function(path, x, y, w, h, isForeground) -{ - var dy = Math.min(this.maxHeight, Math.round(h / 5)); - - if (isForeground) - { - path.moveTo(0, dy); - path.curveTo(0, 2 * dy, w, 2 * dy, w, dy); - } - else - { - path.moveTo(0, dy); - path.curveTo(0, -dy / 3, w, -dy / 3, w, dy); - path.lineTo(w, h - dy); - path.curveTo(w, h + dy / 3, 0, h + dy / 3, 0, h - dy); - path.close(); - } -}; diff --git a/src/js/shape/mxDoubleEllipse.js b/src/js/shape/mxDoubleEllipse.js deleted file mode 100644 index 7854851..0000000 --- a/src/js/shape/mxDoubleEllipse.js +++ /dev/null @@ -1,203 +0,0 @@ -/** - * $Id: mxDoubleEllipse.js,v 1.19 2012-05-21 18:27:17 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxDoubleEllipse - * - * Extends <mxShape> to implement a double ellipse shape. - * This shape is registered under <mxConstants.SHAPE_DOUBLE_ELLIPSE> - * in <mxCellRenderer>. - * - * Constructor: mxDoubleEllipse - * - * Constructs a new ellipse shape. - * - * Parameters: - * - * bounds - <mxRectangle> that defines the bounds. This is stored in - * <mxShape.bounds>. - * fill - String that defines the fill color. This is stored in <fill>. - * stroke - String that defines the stroke color. This is stored in <stroke>. - * strokewidth - Optional integer that defines the stroke width. Default is - * 1. This is stored in <strokewidth>. - */ -function mxDoubleEllipse(bounds, fill, stroke, strokewidth) -{ - this.bounds = bounds; - this.fill = fill; - this.stroke = stroke; - this.strokewidth = (strokewidth != null) ? strokewidth : 1; -}; - -/** - * Extends mxShape. - */ -mxDoubleEllipse.prototype = new mxShape(); -mxDoubleEllipse.prototype.constructor = mxDoubleEllipse; - -/** - * Variable: vmlNodes - * - * Adds local references to <mxShape.vmlNodes>. - */ -mxDoubleEllipse.prototype.vmlNodes = mxDoubleEllipse.prototype.vmlNodes.concat(['background', 'foreground']); - -/** - * Variable: mixedModeHtml - * - * Overrides the parent value with false, meaning it will - * draw in VML in mixed Html mode. - */ -mxDoubleEllipse.prototype.mixedModeHtml = false; - -/** - * Variable: preferModeHtml - * - * Overrides the parent value with false, meaning it will - * draw as VML in prefer Html mode. - */ -mxDoubleEllipse.prototype.preferModeHtml = false; - -/** - * Variable: vmlScale - * - * Renders VML with a scale of 2. - */ -mxDoubleEllipse.prototype.vmlScale = 2; - -/** - * Function: createVml - * - * Creates and returns the VML node to represent this shape. - */ -mxDoubleEllipse.prototype.createVml = function() -{ - var node = document.createElement('v:group'); - - // Draws the background - this.background = document.createElement('v:arc'); - this.background.startangle = '0'; - this.background.endangle = '360'; - this.configureVmlShape(this.background); - - node.appendChild(this.background); - - // Ignores values that only apply to the background - this.label = this.background; - this.isShadow = false; - this.fill = null; - - // Draws the foreground - this.foreground = document.createElement('v:oval'); - this.configureVmlShape(this.foreground); - - node.appendChild(this.foreground); - - this.stroke = null; - this.configureVmlShape(node); - - return node; -}; - -/** - * Function: redrawVml - * - * Updates the VML node(s) to reflect the latest bounds and scale. - */ -mxDoubleEllipse.prototype.redrawVml = function() -{ - this.updateVmlShape(this.node); - this.updateVmlShape(this.background); - this.updateVmlShape(this.foreground); - - var inset = Math.round((this.strokewidth + 3) * this.scale) * this.vmlScale; - var w = Math.round(this.bounds.width * this.vmlScale); - var h = Math.round(this.bounds.height * this.vmlScale); - - this.foreground.style.top = inset + 'px'; // relative - this.foreground.style.left = inset + 'px'; // relative - this.foreground.style.width = Math.max(0, w - 2 * inset) + 'px'; - this.foreground.style.height = Math.max(0, h - 2 * inset) + 'px'; -}; - -/** - * Function: createSvg - * - * Creates and returns the SVG node(s) to represent this shape. - */ -mxDoubleEllipse.prototype.createSvg = function() -{ - var g = this.createSvgGroup('ellipse'); - this.foreground = document.createElementNS(mxConstants.NS_SVG, 'ellipse'); - - if (this.stroke != null) - { - this.foreground.setAttribute('stroke', this.stroke); - } - else - { - this.foreground.setAttribute('stroke', 'none'); - } - - this.foreground.setAttribute('fill', 'none'); - g.appendChild(this.foreground); - - return g; -}; - -/** - * Function: redrawSvg - * - * Updates the SVG node(s) to reflect the latest bounds and scale. - */ -mxDoubleEllipse.prototype.redrawSvg = function() -{ - if (this.crisp) - { - this.innerNode.setAttribute('shape-rendering', 'crispEdges'); - this.foreground.setAttribute('shape-rendering', 'crispEdges'); - } - else - { - this.innerNode.removeAttribute('shape-rendering'); - this.foreground.removeAttribute('shape-rendering'); - } - - this.updateSvgNode(this.innerNode); - this.updateSvgNode(this.shadowNode); - this.updateSvgNode(this.foreground, (this.strokewidth + 3) * this.scale); - - if (this.isDashed) - { - var phase = Math.max(1, Math.round(3 * this.scale * this.strokewidth)); - this.innerNode.setAttribute('stroke-dasharray', phase + ' ' + phase); - } -}; - -/** - * Function: updateSvgNode - * - * Updates the given node to reflect the new <bounds> and <scale>. - */ -mxDoubleEllipse.prototype.updateSvgNode = function(node, inset) -{ - inset = (inset != null) ? inset : 0; - - if (node != null) - { - var strokeWidth = Math.round(Math.max(1, this.strokewidth * this.scale)); - node.setAttribute('stroke-width', strokeWidth); - - node.setAttribute('cx', this.bounds.x + this.bounds.width / 2); - node.setAttribute('cy', this.bounds.y + this.bounds.height / 2); - node.setAttribute('rx', Math.max(0, this.bounds.width / 2 - inset)); - node.setAttribute('ry', Math.max(0, this.bounds.height / 2 - inset)); - - // Updates the transform of the shadow - if (this.shadowNode != null) - { - this.shadowNode.setAttribute('transform', this.getSvgShadowTransform()); - } - } -}; diff --git a/src/js/shape/mxEllipse.js b/src/js/shape/mxEllipse.js deleted file mode 100644 index f3882cf..0000000 --- a/src/js/shape/mxEllipse.js +++ /dev/null @@ -1,132 +0,0 @@ -/** - * $Id: mxEllipse.js,v 1.20 2012-04-04 07:34:50 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxEllipse - * - * Extends <mxShape> to implement an ellipse shape. - * This shape is registered under <mxConstants.SHAPE_ELLIPSE> - * in <mxCellRenderer>. - * - * Constructor: mxEllipse - * - * Constructs a new ellipse shape. - * - * Parameters: - * - * bounds - <mxRectangle> that defines the bounds. This is stored in - * <mxShape.bounds>. - * fill - String that defines the fill color. This is stored in <fill>. - * stroke - String that defines the stroke color. This is stored in <stroke>. - * strokewidth - Optional integer that defines the stroke width. Default is - * 1. This is stored in <strokewidth>. - */ -function mxEllipse(bounds, fill, stroke, strokewidth) -{ - this.bounds = bounds; - this.fill = fill; - this.stroke = stroke; - this.strokewidth = (strokewidth != null) ? strokewidth : 1; -}; - -/** - * Extends mxShape. - */ -mxEllipse.prototype = new mxShape(); -mxEllipse.prototype.constructor = mxEllipse; - -/** - * Variable: mixedModeHtml - * - * Overrides the parent value with false, meaning it will - * draw in VML in mixed Html mode. - */ -mxEllipse.prototype.mixedModeHtml = false; - -/** - * Variable: preferModeHtml - * - * Overrides the parent value with false, meaning it will - * draw as VML in prefer Html mode. - */ -mxEllipse.prototype.preferModeHtml = false; - -/** - * Function: createVml - * - * Creates and returns the VML node to represent this shape. - */ -mxEllipse.prototype.createVml = function() -{ - // Uses an arc not an oval to make sure the - // textbox fills out the outer bounds of the - // circle, not just the inner rectangle - var node = document.createElement('v:arc'); - node.startangle = '0'; - node.endangle = '360'; - this.configureVmlShape(node); - - return node; -}; - -/** - * Function: createSvg - * - * Creates and returns the SVG node(s) to represent this shape. - */ -mxEllipse.prototype.createSvg = function() -{ - return this.createSvgGroup('ellipse'); -}; - -/** - * Function: redrawSvg - * - * Updates the SVG node(s) to reflect the latest bounds and scale. - */ -mxEllipse.prototype.redrawSvg = function() -{ - if (this.crisp) - { - this.innerNode.setAttribute('shape-rendering', 'crispEdges'); - } - else - { - this.innerNode.removeAttribute('shape-rendering'); - } - - this.updateSvgNode(this.innerNode); - this.updateSvgNode(this.shadowNode); -}; - -/** - * Function: updateSvgNode - * - * Updates the given node to reflect the new <bounds> and <scale>. - */ -mxEllipse.prototype.updateSvgNode = function(node) -{ - if (node != null) - { - var strokeWidth = Math.round(Math.max(1, this.strokewidth * this.scale)); - node.setAttribute('stroke-width', strokeWidth); - - node.setAttribute('cx', this.bounds.x + this.bounds.width / 2); - node.setAttribute('cy', this.bounds.y + this.bounds.height / 2); - node.setAttribute('rx', this.bounds.width / 2); - node.setAttribute('ry', this.bounds.height / 2); - - // Updates the shadow offset - if (this.shadowNode != null) - { - this.shadowNode.setAttribute('transform', this.getSvgShadowTransform()); - } - - if (this.isDashed) - { - var phase = Math.max(1, Math.round(3 * this.scale * this.strokewidth)); - node.setAttribute('stroke-dasharray', phase + ' ' + phase); - } - } -}; diff --git a/src/js/shape/mxHexagon.js b/src/js/shape/mxHexagon.js deleted file mode 100644 index 7fa45a3..0000000 --- a/src/js/shape/mxHexagon.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * $Id: mxHexagon.js,v 1.8 2011-09-02 10:01:00 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxHexagon - * - * Implementation of the hexagon shape. - * - * Constructor: mxHexagon - * - * Constructs a new hexagon shape. - */ -function mxHexagon() { }; - -/** - * Extends <mxActor>. - */ -mxHexagon.prototype = new mxActor(); -mxHexagon.prototype.constructor = mxHexagon; - -/** - * Function: redrawPath - * - * Draws the path for this shape. This method uses the <mxPath> - * abstraction to paint the shape for VML and SVG. - */ -mxHexagon.prototype.redrawPath = function(path, x, y, w, h) -{ - path.moveTo(0.25 * w, 0); - path.lineTo(0.75 * w, 0); - path.lineTo(w, 0.5 * h); - path.lineTo(0.75 * w, h); - path.lineTo(0.25 * w, h); - path.lineTo(0, 0.5 * h); - path.close(); -}; diff --git a/src/js/shape/mxImageShape.js b/src/js/shape/mxImageShape.js deleted file mode 100644 index 2f1eab0..0000000 --- a/src/js/shape/mxImageShape.js +++ /dev/null @@ -1,405 +0,0 @@ -/** - * $Id: mxImageShape.js,v 1.67 2012-04-22 10:16:23 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxImageShape - * - * Extends <mxShape> to implement an image shape. This shape is registered - * under <mxConstants.SHAPE_IMAGE> in <mxCellRenderer>. - * - * Constructor: mxImageShape - * - * Constructs a new image shape. - * - * Parameters: - * - * bounds - <mxRectangle> that defines the bounds. This is stored in - * <mxShape.bounds>. - * image - String that specifies the URL of the image. This is stored in - * <image>. - * fill - String that defines the fill color. This is stored in <fill>. - * stroke - String that defines the stroke color. This is stored in <stroke>. - * strokewidth - Optional integer that defines the stroke width. Default is - * 0. This is stored in <strokewidth>. - */ -function mxImageShape(bounds, image, fill, stroke, strokewidth) -{ - this.bounds = bounds; - this.image = (image != null) ? image : ''; - this.fill = fill; - this.stroke = stroke; - this.strokewidth = (strokewidth != null) ? strokewidth : 1; - this.isShadow = false; -}; - -/** - * Extends mxShape. - */ -mxImageShape.prototype = new mxShape(); -mxImageShape.prototype.constructor = mxImageShape; - -/** - * Variable: crisp - * - * Disables crisp rendering via attributes. Image quality defines the rendering - * quality. Default is false. - */ -mxImageShape.prototype.crisp = false; - -/** - * Variable: preserveImageAspect - * - * Switch to preserve image aspect. Default is true. - */ -mxImageShape.prototype.preserveImageAspect = true; - -/** - * Function: apply - * - * Overrides <mxShape.apply> to replace the fill and stroke colors with the - * respective values from <mxConstants.STYLE_IMAGE_BACKGROUND> and - * <mxConstants.STYLE_IMAGE_BORDER>. - * - * Applies the style of the given <mxCellState> to the shape. This - * implementation assigns the following styles to local fields: - * - * - <mxConstants.STYLE_IMAGE_BACKGROUND> => fill - * - <mxConstants.STYLE_IMAGE_BORDER> => stroke - * - * Parameters: - * - * state - <mxCellState> of the corresponding cell. - */ -mxImageShape.prototype.apply = function(state) -{ - mxShape.prototype.apply.apply(this, arguments); - - this.fill = null; - this.stroke = null; - - if (this.style != null) - { - this.fill = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BACKGROUND); - this.stroke = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_BORDER); - this.preserveImageAspect = mxUtils.getNumber(this.style, mxConstants.STYLE_IMAGE_ASPECT, 1) == 1; - this.gradient = null; - } -}; - -/** - * Function: create - * - * Override to create HTML regardless of gradient and - * rounded property. - */ -mxImageShape.prototype.create = function() -{ - var node = null; - - if (this.dialect == mxConstants.DIALECT_SVG) - { - // Workaround: To avoid control-click on images in Firefox to - // open the image in a new window, this image needs to be placed - // inside a group with a rectangle in the foreground which has a - // fill property but no visibility and absorbs all events. - // The image in turn must have all pointer-events disabled. - node = this.createSvgGroup('rect'); - this.innerNode.setAttribute('visibility', 'hidden'); - this.innerNode.setAttribute('pointer-events', 'fill'); - - this.imageNode = document.createElementNS(mxConstants.NS_SVG, 'image'); - this.imageNode.setAttributeNS(mxConstants.NS_XLINK, 'xlink:href', this.image); - this.imageNode.setAttribute('style', 'pointer-events:none'); - this.configureSvgShape(this.imageNode); - - // Removes invalid attributes on the image node - this.imageNode.removeAttribute('stroke'); - this.imageNode.removeAttribute('fill'); - node.insertBefore(this.imageNode, this.innerNode); - - // Inserts node for background and border color rendering - if ((this.fill != null && this.fill != mxConstants.NONE) || - (this.stroke != null && this.stroke != mxConstants.NONE)) - { - this.bg = document.createElementNS(mxConstants.NS_SVG, 'rect'); - node.insertBefore(this.bg, node.firstChild); - } - - // Preserves image aspect as default - if (!this.preserveImageAspect) - { - this.imageNode.setAttribute('preserveAspectRatio', 'none'); - } - } - else - { - // Uses VML image for all non-embedded images in IE to support better - // image flipping quality and avoid workarounds for event redirection - var flipH = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_FLIPH, 0) == 1; - var flipV = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_FLIPV, 0) == 1; - var img = this.image.toUpperCase(); - - // Handles non-flipped embedded images in IE6 - if (mxClient.IS_IE && !flipH && !flipV && img.substring(0, 6) == 'MHTML:') - { - // LATER: Check if outer DIV is required or if aspect can be implemented - // by adding an offset to the image loading or the background via CSS. - this.imageNode = document.createElement('DIV'); - this.imageNode.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader ' + - '(src=\'' + this.image + '\', sizingMethod=\'scale\')'; - - node = document.createElement('DIV'); - this.configureHtmlShape(node); - node.appendChild(this.imageNode); - } - // Handles all data URL images and HTML images for IE9 with no VML support (in SVG mode) - else if (!mxClient.IS_IE || img.substring(0, 5) == 'DATA:' || document.documentMode >= 9) - { - this.imageNode = document.createElement('img'); - this.imageNode.setAttribute('src', this.image); - this.imageNode.setAttribute('border', '0'); - this.imageNode.style.position = 'absolute'; - this.imageNode.style.width = '100%'; - this.imageNode.style.height = '100%'; - - node = document.createElement('DIV'); - this.configureHtmlShape(node); - node.appendChild(this.imageNode); - } - else - { - this.imageNode = document.createElement('v:image'); - this.imageNode.style.position = 'absolute'; - this.imageNode.src = this.image; - - // Needed to draw the background and border but known - // to cause problems in print preview with https - node = document.createElement('DIV'); - this.configureHtmlShape(node); - - // Workaround for cropped images in IE7/8 - node.style.overflow = 'visible'; - node.appendChild(this.imageNode); - } - } - - return node; -}; - -/** - * Function: updateAspect - * - * Updates the aspect of the image for the given image width and height. - */ -mxImageShape.prototype.updateAspect = function(w, h) -{ - var s = Math.min(this.bounds.width / w, this.bounds.height / h); - w = Math.max(0, Math.round(w * s)); - h = Math.max(0, Math.round(h * s)); - var x0 = Math.max(0, Math.round((this.bounds.width - w) / 2)); - var y0 = Math.max(0, Math.round((this.bounds.height - h) / 2)); - var st = this.imageNode.style; - - // Positions the child node relative to the parent node - if (this.imageNode.parentNode == this.node) - { - // Workaround for duplicate offset in VML in IE8 is - // to use parent padding instead of left and top - this.node.style.paddingLeft = x0 + 'px'; - this.node.style.paddingTop = y0 + 'px'; - } - else - { - st.left = (Math.round(this.bounds.x) + x0) + 'px'; - st.top = (Math.round(this.bounds.y) + y0) + 'px'; - } - - st.width = w + 'px'; - st.height = h + 'px'; -}; - -/** - * Function: scheduleUpdateAspect - * - * Schedules an asynchronous <updateAspect> using the current <image>. - */ -mxImageShape.prototype.scheduleUpdateAspect = function() -{ - var img = new Image(); - - img.onload = mxUtils.bind(this, function() - { - mxImageShape.prototype.updateAspect.call(this, img.width, img.height); - }); - - img.src = this.image; -}; - -/** - * Function: redraw - * - * Overrides <mxShape.redraw> to preserve the aspect ratio of images. - */ -mxImageShape.prototype.redraw = function() -{ - mxShape.prototype.redraw.apply(this, arguments); - - if (this.imageNode != null && this.bounds != null) - { - // Horizontal and vertical flipping - var flipH = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_FLIPH, 0) == 1; - var flipV = mxUtils.getValue(this.style, mxConstants.STYLE_IMAGE_FLIPV, 0) == 1; - - if (this.dialect == mxConstants.DIALECT_SVG) - { - var sx = 1; - var sy = 1; - var dx = 0; - var dy = 0; - - if (flipH) - { - sx = -1; - dx = -this.bounds.width - 2 * this.bounds.x; - } - - if (flipV) - { - sy = -1; - dy = -this.bounds.height - 2 * this.bounds.y; - } - - // Adds image tansformation to existing transforms - var transform = (this.imageNode.getAttribute('transform') || '') + - ' scale('+sx+' '+sy+')'+ ' translate('+dx+' '+dy+')'; - this.imageNode.setAttribute('transform', transform); - } - else - { - // Sets default size (no aspect) - if (this.imageNode.nodeName != 'DIV') - { - this.imageNode.style.width = Math.max(0, Math.round(this.bounds.width)) + 'px'; - this.imageNode.style.height = Math.max(0, Math.round(this.bounds.height)) + 'px'; - } - - // Preserves image aspect - if (this.preserveImageAspect) - { - this.scheduleUpdateAspect(); - } - - if (flipH || flipV) - { - if (mxUtils.isVml(this.imageNode)) - { - if (flipH && flipV) - { - this.imageNode.style.rotation = '180'; - } - else if (flipH) - { - this.imageNode.style.flip = 'x'; - } - else - { - this.imageNode.style.flip = 'y'; - } - } - else - { - var filter = (this.imageNode.nodeName == 'DIV') ? 'progid:DXImageTransform.Microsoft.AlphaImageLoader ' + - '(src=\'' + this.image + '\', sizingMethod=\'scale\')' : ''; - - if (flipH && flipV) - { - filter += 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)'; - } - else if (flipH) - { - filter += 'progid:DXImageTransform.Microsoft.BasicImage(mirror=1)'; - } - else - { - filter += 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)'; - } - - if (this.imageNode.style.filter != filter) - { - this.imageNode.style.filter = filter; - } - } - } - } - } -}; - -/** - * Function: configureTransparentBackground - * - * Workaround for security warning in IE if this is used in the overlay pane - * of a diagram. - */ -mxImageShape.prototype.configureTransparentBackground = function(node) -{ - // do nothing -}; - -/** - * Function: redrawSvg - * - * Updates the SVG node(s) to reflect the latest bounds and scale. - */ -mxImageShape.prototype.redrawSvg = function() -{ - this.updateSvgShape(this.innerNode); - this.updateSvgShape(this.imageNode); - - if (this.bg != null) - { - this.updateSvgShape(this.bg); - - if (this.fill != null) - { - this.bg.setAttribute('fill', this.fill); - } - else - { - this.bg.setAttribute('fill', 'none'); - } - - if (this.stroke != null) - { - this.bg.setAttribute('stroke', this.stroke); - } - else - { - this.bg.setAttribute('stroke', 'none'); - } - - this.bg.setAttribute('shape-rendering', 'crispEdges'); - } -}; - -/** - * Function: configureSvgShape - * - * Extends method to set opacity on images. - */ -mxImageShape.prototype.configureSvgShape = function(node) -{ - mxShape.prototype.configureSvgShape.apply(this, arguments); - - if (this.imageNode != null) - { - if (this.opacity != null) - { - this.imageNode.setAttribute('opacity', this.opacity / 100); - } - else - { - this.imageNode.removeAttribute('opacity'); - } - } -}; diff --git a/src/js/shape/mxLabel.js b/src/js/shape/mxLabel.js deleted file mode 100644 index c31f3bf..0000000 --- a/src/js/shape/mxLabel.js +++ /dev/null @@ -1,427 +0,0 @@ -/** - * $Id: mxLabel.js,v 1.40 2012-05-22 16:10:12 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxLabel - * - * Extends <mxShape> to implement an image shape with a label. - * This shape is registered under <mxConstants.SHAPE_LABEL> in - * <mxCellRenderer>. - * - * Constructor: mxLabel - * - * Constructs a new label shape. - * - * Parameters: - * - * bounds - <mxRectangle> that defines the bounds. This is stored in - * <mxShape.bounds>. - * fill - String that defines the fill color. This is stored in <fill>. - * stroke - String that defines the stroke color. This is stored in <stroke>. - * strokewidth - Optional integer that defines the stroke width. Default is - * 1. This is stored in <strokewidth>. - */ -function mxLabel(bounds, fill, stroke, strokewidth) -{ - this.bounds = bounds; - this.fill = fill; - this.stroke = stroke; - this.strokewidth = (strokewidth != null) ? strokewidth : 1; -}; - -/** - * Extends mxShape. - */ -mxLabel.prototype = new mxShape(); -mxLabel.prototype.constructor = mxLabel; - -/** - * Variable: vmlNodes - * - * Adds local references to <mxShape.vmlNodes>. - */ -mxLabel.prototype.vmlNodes = mxLabel.prototype.vmlNodes.concat(['label', 'imageNode', 'indicatorImageNode', 'rectNode']); - -/** - * Variable: imageSize - * - * Default width and height for the image. Default is - * <mxConstants.DEFAULT_IMAGESIZE>. - */ -mxLabel.prototype.imageSize = mxConstants.DEFAULT_IMAGESIZE; - -/** - * Variable: spacing - * - * Default value for spacing. Default is 2. - */ -mxLabel.prototype.spacing = 2; - -/** - * Variable: indicatorSize - * - * Default width and height for the indicicator. Default is - * 10. - */ -mxLabel.prototype.indicatorSize = 10; - -/** - * Variable: indicatorSpacing - * - * Default spacing between image and indicator. Default is 2. - */ -mxLabel.prototype.indicatorSpacing = 2; - -/** - * Variable: opaqueVmlImages - * - * Specifies if all VML images should be rendered without transparency, that - * is, if the current opacity should be ignored for images. Default is false. - */ -mxLabel.prototype.opaqueVmlImages = false; - -/** - * Function: init - * - * Initializes the shape and adds it to the container. This function is - * overridden so that the node is already in the DOM when the indicator - * is added. This is required to access the ownerSVGelement of the - * container in the init function of the indicator. - */ -mxLabel.prototype.init = function(container) -{ - mxShape.prototype.init.apply(this, arguments); - - // Creates the indicator shape after the node was added to the DOM - if (this.indicatorColor != null && this.indicatorShape != null) - { - this.indicator = new this.indicatorShape(); - this.indicator.dialect = this.dialect; - this.indicator.bounds = this.bounds; - this.indicator.fill = this.indicatorColor; - this.indicator.stroke = this.indicatorColor; - this.indicator.gradient = this.indicatorGradientColor; - this.indicator.direction = this.indicatorDirection; - this.indicator.init(this.node); - this.indicatorShape = null; - } -}; - -/** - * Function: reconfigure - * - * Reconfigures this shape. This will update the colors of the indicator - * and reconfigure it if required. - */ -mxLabel.prototype.reconfigure = function() -{ - mxShape.prototype.reconfigure.apply(this); - - if (this.indicator != null) - { - this.indicator.fill = this.indicatorColor; - this.indicator.stroke = this.indicatorColor; - this.indicator.gradient = this.indicatorGradientColor; - this.indicator.direction = this.indicatorDirection; - this.indicator.reconfigure(); - } -}; - -/** - * Function: createHtml - * - * Creates and returns the HTML node to represent this shape. - */ -mxLabel.prototype.createHtml = function() -{ - var name = 'DIV'; - var node = document.createElement(name); - this.configureHtmlShape(node); - - // Adds a small subshape inside this shape - if (this.indicatorImage != null) - { - this.indicatorImageNode = mxUtils.createImage(this.indicatorImage); - this.indicatorImageNode.style.position = 'absolute'; - node.appendChild(this.indicatorImageNode); - } - - // Adds an image node to the div - if (this.image != null) - { - this.imageNode = mxUtils.createImage(this.image); - this.stroke = null; - this.configureHtmlShape(this.imageNode); - mxUtils.setOpacity(this.imageNode, '100'); - node.appendChild(this.imageNode); - } - - return node; -}; - -/** - * Function: createVml - * - * Creates and returns the VML node to represent this shape. - */ -mxLabel.prototype.createVml = function() -{ - var node = document.createElement('v:group'); - - // Background - var name = (this.isRounded) ? 'v:roundrect' : 'v:rect'; - this.rectNode = document.createElement(name); - this.configureVmlShape(this.rectNode); - - // Disables the shadow and configures the enclosing group - this.isShadow = false; - this.configureVmlShape(node); - node.coordorigin = '0,0'; - node.appendChild(this.rectNode); - - // Adds a small subshape inside this shape - if (this.indicatorImage != null) - { - this.indicatorImageNode = this.createVmlImage(this.indicatorImage, (this.opaqueVmlImages) ? null : this.opacity); - node.appendChild(this.indicatorImageNode); - } - - // Adds an image node to the div - if (this.image != null) - { - this.imageNode = this.createVmlImage(this.image, (this.opaqueVmlImages) ? null : this.opacity); - node.appendChild(this.imageNode); - } - - // Container for the label on top of everything - this.label = document.createElement('v:rect'); - this.label.style.top = '0px'; // relative - this.label.style.left = '0px'; // relative - this.label.filled = 'false'; - this.label.stroked = 'false'; - node.appendChild(this.label); - - return node; -}; - -/** - * Function: createVmlImage - * - * Creates an image node for the given image src and opacity to be used in VML. - */ -mxLabel.prototype.createVmlImage = function(src, opacity) -{ - var result = null; - - // Workaround for data URIs not supported in VML and for added - // border around images if opacity is used (not needed in IE9, - // but IMG node is probably better and faster anyway). - if (src.substring(0, 5) == 'data:' || opacity != null) - { - result = document.createElement('img'); - mxUtils.setOpacity(result, opacity); - result.setAttribute('border', '0'); - result.style.position = 'absolute'; - result.setAttribute('src', src); - } - else - { - result = document.createElement('v:image'); - result.src = src; - } - - return result; -}; - -/** - * Function: createSvg - * - * Creates and returns the SVG node to represent this shape. - */ -mxLabel.prototype.createSvg = function() -{ - var g = this.createSvgGroup('rect'); - - // Adds a small subshape to the svg group - if (this.indicatorImage != null) - { - this.indicatorImageNode = document.createElementNS(mxConstants.NS_SVG, 'image'); - this.indicatorImageNode.setAttributeNS(mxConstants.NS_XLINK, 'href', this.indicatorImage); - g.appendChild(this.indicatorImageNode); - - if (this.opacity != null) - { - this.indicatorImageNode.setAttribute('opacity', this.opacity / 100); - } - } - - // Adds an image to the svg group - if (this.image != null) - { - this.imageNode = document.createElementNS(mxConstants.NS_SVG, 'image'); - this.imageNode.setAttributeNS(mxConstants.NS_XLINK, 'href', this.image); - - if (this.opacity != null) - { - this.imageNode.setAttribute('opacity', this.opacity / 100); - } - - // Disables control-click and alt-click in Firefox - this.imageNode.setAttribute('style', 'pointer-events:none'); - this.configureSvgShape(this.imageNode); - g.appendChild(this.imageNode); - } - - return g; -}; - -/** - * Function: redraw - * - * Overrides redraw to define a unified implementation for redrawing - * all supported dialects. - */ -mxLabel.prototype.redraw = function() -{ - this.updateBoundingBox(); - var isSvg = (this.dialect == mxConstants.DIALECT_SVG); - var isVml = mxUtils.isVml(this.node); - - // Updates the bounds of the outermost shape - if (isSvg) - { - this.updateSvgShape(this.innerNode); - - if (this.shadowNode != null) - { - this.updateSvgShape(this.shadowNode); - } - - this.updateSvgGlassPane(); - } - else if (isVml) - { - this.updateVmlShape(this.node); - this.updateVmlShape(this.rectNode); - this.label.style.width = this.node.style.width; - this.label.style.height = this.node.style.height; - - this.updateVmlGlassPane(); - } - else - { - this.updateHtmlShape(this.node); - } - - // Updates the imagewidth and imageheight - var imageWidth = 0; - var imageHeight = 0; - - if (this.imageNode != null) - { - imageWidth = (this.style[mxConstants.STYLE_IMAGE_WIDTH] || - this.imageSize) * this.scale; - imageHeight = (this.style[mxConstants.STYLE_IMAGE_HEIGHT] || - this.imageSize) * this.scale; - } - - // Updates the subshape size and location - var indicatorSpacing = 0; - var indicatorWidth = 0; - var indicatorHeight = 0; - - if (this.indicator != null || this.indicatorImageNode != null) - { - indicatorSpacing = (this.style[mxConstants.STYLE_INDICATOR_SPACING] || - this.indicatorSpacing) * this.scale; - indicatorWidth = (this.style[mxConstants.STYLE_INDICATOR_WIDTH] || - this.indicatorSize) * this.scale; - indicatorHeight = (this.style[mxConstants.STYLE_INDICATOR_HEIGHT] || - this.indicatorSize) * this.scale; - } - - var align = this.style[mxConstants.STYLE_IMAGE_ALIGN]; - var valign = this.style[mxConstants.STYLE_IMAGE_VERTICAL_ALIGN]; - - var inset = this.spacing * this.scale + 5; - var width = Math.max(imageWidth, indicatorWidth); - var height = imageHeight + indicatorSpacing + indicatorHeight; - - var x = (isSvg) ? this.bounds.x : 0; - - if (align == mxConstants.ALIGN_RIGHT) - { - x += this.bounds.width - width - inset; - } - else if (align == mxConstants.ALIGN_CENTER) - { - x += (this.bounds.width - width) / 2; - } - else // default is left - { - x += inset; - } - - var y = (isSvg) ? this.bounds.y : 0; - - if (valign == mxConstants.ALIGN_BOTTOM) - { - y += this.bounds.height - height - inset; - } - else if (valign == mxConstants.ALIGN_TOP) - { - y += inset; - } - else // default is middle - { - y += (this.bounds.height - height) / 2; - } - - // Updates the imagenode - if (this.imageNode != null) - { - if (isSvg) - { - this.imageNode.setAttribute('x', (x + (width - imageWidth) / 2) + 'px'); - this.imageNode.setAttribute('y', y + 'px'); - this.imageNode.setAttribute('width', imageWidth + 'px'); - this.imageNode.setAttribute('height', imageHeight + 'px'); - } - else - { - this.imageNode.style.left = (x + width - imageWidth) + 'px'; - this.imageNode.style.top = y + 'px'; - this.imageNode.style.width = imageWidth + 'px'; - this.imageNode.style.height = imageHeight + 'px'; - this.imageNode.stroked = 'false'; - } - } - - // Updates the subshapenode (aka. indicator) - if (this.indicator != null) - { - this.indicator.bounds = new mxRectangle( - x + (width - indicatorWidth) / 2, - y + imageHeight + indicatorSpacing, - indicatorWidth, indicatorHeight); - this.indicator.redraw(); - } - else if (this.indicatorImageNode != null) - { - if (isSvg) - { - this.indicatorImageNode.setAttribute('x', (x + (width - indicatorWidth) / 2) + 'px'); - this.indicatorImageNode.setAttribute('y', (y + imageHeight + indicatorSpacing) + 'px'); - this.indicatorImageNode.setAttribute('width', indicatorWidth + 'px'); - this.indicatorImageNode.setAttribute('height', indicatorHeight + 'px'); - } - else - { - this.indicatorImageNode.style.left = (x + (width - indicatorWidth) / 2) + 'px'; - this.indicatorImageNode.style.top = (y + imageHeight + indicatorSpacing) + 'px'; - this.indicatorImageNode.style.width = indicatorWidth + 'px'; - this.indicatorImageNode.style.height = indicatorHeight + 'px'; - } - } -}; diff --git a/src/js/shape/mxLine.js b/src/js/shape/mxLine.js deleted file mode 100644 index 5ef3eb0..0000000 --- a/src/js/shape/mxLine.js +++ /dev/null @@ -1,217 +0,0 @@ -/** - * $Id: mxLine.js,v 1.36 2012-03-30 04:44:59 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxLine - * - * Extends <mxShape> to implement a horizontal line shape. - * This shape is registered under <mxConstants.SHAPE_LINE> in - * <mxCellRenderer>. - * - * Constructor: mxLine - * - * Constructs a new line shape. - * - * Parameters: - * - * bounds - <mxRectangle> that defines the bounds. This is stored in - * <mxShape.bounds>. - * stroke - String that defines the stroke color. Default is 'black'. This is - * stored in <stroke>. - * strokewidth - Optional integer that defines the stroke width. Default is - * 1. This is stored in <strokewidth>. - */ -function mxLine(bounds, stroke, strokewidth) -{ - this.bounds = bounds; - this.stroke = stroke; - this.strokewidth = (strokewidth != null) ? strokewidth : 1; -}; - -/** - * Extends mxShape. - */ -mxLine.prototype = new mxShape(); -mxLine.prototype.constructor = mxLine; - -/** - * Variable: vmlNodes - * - * Adds local references to <mxShape.vmlNodes>. - */ -mxLine.prototype.vmlNodes = mxLine.prototype.vmlNodes.concat(['label', 'innerNode']); - -/** - * Variable: mixedModeHtml - * - * Overrides the parent value with false, meaning it will - * draw in VML in mixed Html mode. - */ -mxLine.prototype.mixedModeHtml = false; - -/** - * Variable: preferModeHtml - * - * Overrides the parent value with false, meaning it will - * draw as VML in prefer Html mode. - */ -mxLine.prototype.preferModeHtml = false; - -/** - * Function: clone - * - * Overrides the clone method to add special fields. - */ -mxLine.prototype.clone = function() -{ - var clone = new mxLine(this.bounds, - this.stroke, this.strokewidth); - clone.isDashed = this.isDashed; - - return clone; -}; - -/** - * Function: createVml - * - * Creates and returns the VML node to represent this shape. - */ -mxLine.prototype.createVml = function() -{ - var node = document.createElement('v:group'); - node.style.position = 'absolute'; - - // Represents the text label container - this.label = document.createElement('v:rect'); - this.label.style.position = 'absolute'; - this.label.stroked = 'false'; - this.label.filled = 'false'; - node.appendChild(this.label); - - // Represents the straight line shape - this.innerNode = document.createElement('v:shape'); - this.configureVmlShape(this.innerNode); - node.appendChild(this.innerNode); - - return node; -}; - -/** - * Function: redrawVml - * - * Redraws this VML shape by invoking <updateVmlShape> on this.node. - */ -mxLine.prototype.reconfigure = function() -{ - if (mxUtils.isVml(this.node)) - { - this.configureVmlShape(this.innerNode); - } - else - { - mxShape.prototype.reconfigure.apply(this, arguments); - } -}; - -/** - * Function: redrawVml - * - * Updates the VML node(s) to reflect the latest bounds and scale. - */ -mxLine.prototype.redrawVml = function() -{ - this.updateVmlShape(this.node); - this.updateVmlShape(this.label); - - this.innerNode.coordsize = this.node.coordsize; - this.innerNode.strokeweight = (this.strokewidth * this.scale) + 'px'; - this.innerNode.style.width = this.node.style.width; - this.innerNode.style.height = this.node.style.height; - - var w = this.bounds.width; - var h =this.bounds.height; - - if (this.direction == mxConstants.DIRECTION_NORTH || - this.direction == mxConstants.DIRECTION_SOUTH) - { - this.innerNode.path = 'm ' + Math.round(w / 2) + ' 0' + - ' l ' + Math.round(w / 2) + ' ' + Math.round(h) + ' e'; - } - else - { - this.innerNode.path = 'm 0 ' + Math.round(h / 2) + - ' l ' + Math.round(w) + ' ' + Math.round(h / 2) + ' e'; - } -}; - -/** - * Function: createSvg - * - * Creates and returns the SVG node(s) to represent this shape. - */ -mxLine.prototype.createSvg = function() -{ - var g = this.createSvgGroup('path'); - - // Creates an invisible shape around the path for easier - // selection with the mouse. Note: Firefox does not ignore - // the value of the stroke attribute for pointer-events: stroke. - // It does, however, ignore the visibility attribute. - this.pipe = this.createSvgPipe(); - g.appendChild(this.pipe); - - return g; -}; - -/** - * Function: redrawSvg - * - * Updates the SVG node(s) to reflect the latest bounds and scale. - */ -mxLine.prototype.redrawSvg = function() -{ - var strokeWidth = Math.round(Math.max(1, this.strokewidth * this.scale)); - this.innerNode.setAttribute('stroke-width', strokeWidth); - - if (this.bounds != null) - { - var x = this.bounds.x; - var y = this.bounds.y; - var w = this.bounds.width; - var h = this.bounds.height; - - var d = null; - - if (this.direction == mxConstants.DIRECTION_NORTH || this.direction == mxConstants.DIRECTION_SOUTH) - { - d = 'M ' + Math.round(x + w / 2) + ' ' + Math.round(y) + ' L ' + Math.round(x + w / 2) + ' ' + Math.round(y + h); - } - else - { - d = 'M ' + Math.round(x) + ' ' + Math.round(y + h / 2) + ' L ' + Math.round(x + w) + ' ' + Math.round(y + h / 2); - } - - this.innerNode.setAttribute('d', d); - this.pipe.setAttribute('d', d); - this.pipe.setAttribute('stroke-width', this.strokewidth + mxShape.prototype.SVG_STROKE_TOLERANCE); - - this.updateSvgTransform(this.innerNode, false); - this.updateSvgTransform(this.pipe, false); - - if (this.crisp) - { - this.innerNode.setAttribute('shape-rendering', 'crispEdges'); - } - else - { - this.innerNode.removeAttribute('shape-rendering'); - } - - if (this.isDashed) - { - var phase = Math.max(1, Math.round(3 * this.scale * this.strokewidth)); - this.innerNode.setAttribute('stroke-dasharray', phase + ' ' + phase); - } - } -}; diff --git a/src/js/shape/mxMarker.js b/src/js/shape/mxMarker.js deleted file mode 100644 index cfd6f66..0000000 --- a/src/js/shape/mxMarker.js +++ /dev/null @@ -1,267 +0,0 @@ -/** - * $Id: mxMarker.js,v 1.19 2012-03-30 12:51:58 david Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -var mxMarker = -{ - /** - * Class: mxMarker - * - * A static class that implements all markers for VML and SVG using a - * registry. NOTE: The signatures in this class will change. - * - * Variable: markers - * - * Maps from markers names to functions to paint the markers. - */ - markers: [], - - /** - * Function: paintMarker - * - * Paints the given marker. - */ - paintMarker: function(node, type, p0, pe, color, strokewidth, size, scale, x0, y0, source, style) - { - var marker = mxMarker.markers[type]; - var result = null; - - if (marker != null) - { - var isVml = mxUtils.isVml(node); - - // Computes the norm and the inverse norm - var dx = pe.x - p0.x; - var dy = pe.y - p0.y; - - if (isNaN(dx) || isNaN(dy)) - { - return; - } - - var dist = Math.max(1, Math.sqrt(dx * dx + dy * dy)); - var nx = dx * scale / dist; - var ny = dy * scale / dist; - - pe = pe.clone(); - - if (isVml) - { - pe.x -= x0; - pe.y -= y0; - } - - // Handles start-/endFill style - var filled = true; - var key = (source) ? mxConstants.STYLE_STARTFILL : mxConstants.STYLE_ENDFILL; - - if (style[key] == 0) - { - filled = false; - } - - if (isVml) - { - // Opacity is updated in reconfigure, use nf in path for no fill - node.strokecolor = color; - - if (filled) - { - node.fillcolor = color; - } - else - { - node.filled = 'false'; - } - } - else - { - node.setAttribute('stroke', color); - - var op = (style.opacity != null) ? style.opacity / 100 : 1; - node.setAttribute('stroke-opacity', op); - - if (filled) - { - node.setAttribute('fill', color); - node.setAttribute('fill-opacity', op); - } - else - { - node.setAttribute('fill', 'none'); - } - } - - result = marker.call(this, node, type, pe, nx, ny, strokewidth, size, scale, isVml); - } - - return result; - } - -}; - -(function() -{ - /** - * Drawing of the classic and block arrows. - */ - var tmp = function(node, type, pe, nx, ny, strokewidth, size, scale, isVml) - { - // The angle of the forward facing arrow sides against the x axis is - // 26.565 degrees, 1/sin(26.565) = 2.236 / 2 = 1.118 ( / 2 allows for - // only half the strokewidth is processed ). - var endOffsetX = nx * strokewidth * 1.118; - var endOffsetY = ny * strokewidth * 1.118; - pe.x -= endOffsetX; - pe.y -= endOffsetY; - - nx = nx * (size + strokewidth); - ny = ny * (size + strokewidth); - - if (isVml) - { - node.path = 'm' + Math.round(pe.x) + ',' + Math.round(pe.y) + - ' l' + Math.round(pe.x - nx - ny / 2) + ' ' + Math.round(pe.y - ny + nx / 2) + - ((type != mxConstants.ARROW_CLASSIC) ? '' : - ' ' + Math.round(pe.x - nx * 3 / 4) + ' ' + Math.round(pe.y - ny * 3 / 4)) + - ' ' + Math.round(pe.x + ny / 2 - nx) + ' ' + Math.round(pe.y - ny - nx / 2) + - ' x e'; - node.setAttribute('strokeweight', (strokewidth * scale) + 'px'); - } - else - { - node.setAttribute('d', 'M ' + pe.x + ' ' + pe.y + - ' L ' + (pe.x - nx - ny / 2) + ' ' + (pe.y - ny + nx / 2) + - ((type != mxConstants.ARROW_CLASSIC) ? '' : - ' L ' + (pe.x - nx * 3 / 4) + ' ' + (pe.y - ny * 3 / 4)) + - ' L ' + (pe.x + ny / 2 - nx) + ' ' + (pe.y - ny - nx / 2) + - ' z'); - node.setAttribute('stroke-width', strokewidth * scale); - } - - var f = (type != mxConstants.ARROW_CLASSIC) ? 1 : 3 / 4; - return new mxPoint(-nx * f - endOffsetX, -ny * f - endOffsetY); - }; - - mxMarker.markers[mxConstants.ARROW_CLASSIC] = tmp; - mxMarker.markers[mxConstants.ARROW_BLOCK] = tmp; -}()); - -mxMarker.markers[mxConstants.ARROW_OPEN] = function(node, type, pe, nx, ny, strokewidth, size, scale, isVml) -{ - // The angle of the forward facing arrow sides against the x axis is - // 26.565 degrees, 1/sin(26.565) = 2.236 / 2 = 1.118 ( / 2 allows for - // only half the strokewidth is processed ). - var endOffsetX = nx * strokewidth * 1.118; - var endOffsetY = ny * strokewidth * 1.118; - pe.x -= endOffsetX; - pe.y -= endOffsetY; - - nx = nx * (size + strokewidth); - ny = ny * (size + strokewidth); - - if (isVml) - { - node.path = 'm' + Math.round(pe.x - nx - ny / 2) + ' ' + Math.round(pe.y - ny + nx / 2) + - ' l' + Math.round(pe.x) + ' ' + Math.round(pe.y) + - ' ' + Math.round(pe.x + ny / 2 - nx) + ' ' + Math.round(pe.y - ny - nx / 2) + - ' e nf'; - node.setAttribute('strokeweight', (strokewidth * scale) + 'px'); - } - else - { - node.setAttribute('d', 'M ' + (pe.x - nx - ny / 2) + ' ' + (pe.y - ny + nx / 2) + - ' L ' + (pe.x) + ' ' + (pe.y) + - ' L ' + (pe.x + ny / 2 - nx) + ' ' + (pe.y - ny - nx / 2)); - node.setAttribute('stroke-width', strokewidth * scale); - node.setAttribute('fill', 'none'); - } - - return new mxPoint(-endOffsetX * 2, -endOffsetY * 2); -}; - -mxMarker.markers[mxConstants.ARROW_OVAL] = function(node, type, pe, nx, ny, strokewidth, size, scale, isVml) -{ - nx *= size; - ny *= size; - - nx *= 0.5 + strokewidth / 2; - ny *= 0.5 + strokewidth / 2; - - var absSize = size * scale; - var radius = absSize / 2; - - if (isVml) - { - node.path = 'm' + Math.round(pe.x + radius) + ' ' + Math.round(pe.y) + - ' at ' + Math.round(pe.x - radius) + ' ' + Math.round(pe.y - radius) + - ' ' + Math.round(pe.x + radius) + ' ' + Math.round(pe.y + radius) + - ' ' + Math.round(pe.x + radius) + ' ' + Math.round(pe.y) + - ' ' + Math.round(pe.x + radius) + ' ' + Math.round(pe.y) + - ' x e'; - - node.setAttribute('strokeweight', (strokewidth * scale) + 'px'); - } - else - { - node.setAttribute('d', 'M ' + (pe.x - radius) + ' ' + (pe.y) + - ' a ' + (radius) + ' ' + (radius) + - ' 0 1,1 ' + (absSize) + ' 0' + - ' a ' + (radius) + ' ' + (radius) + - ' 0 1,1 ' + (-absSize) + ' 0 z'); - node.setAttribute('stroke-width', strokewidth * scale); - } - - return new mxPoint(-nx / (2 + strokewidth), -ny / (2 + strokewidth)); -}; - -(function() - { - /** - * Drawing of the diamond and thin diamond markers - */ - var tmp_diamond = function(node, type, pe, nx, ny, strokewidth, size, scale, isVml) - { - // The angle of the forward facing arrow sides against the x axis is - // 45 degrees, 1/sin(45) = 1.4142 / 2 = 0.7071 ( / 2 allows for - // only half the strokewidth is processed ). Or 0.9862 for thin diamond. - // Note these values and the tk variable below are dependent, update - // both together (saves trig hard coding it). - var swFactor = (type == mxConstants.ARROW_DIAMOND) ? 0.7071 : 0.9862; - var endOffsetX = nx * strokewidth * swFactor; - var endOffsetY = ny * strokewidth * swFactor; - - nx = nx * (size + strokewidth); - ny = ny * (size + strokewidth); - - pe.x -= endOffsetX + nx / 2; - pe.y -= endOffsetY + ny / 2; - - // thickness factor for diamond - var tk = ((type == mxConstants.ARROW_DIAMOND) ? 2 : 3.4); - - if (isVml) - { - node.path = 'm' + Math.round(pe.x + nx / 2) + ' ' + Math.round(pe.y + ny / 2) + - ' l' + Math.round(pe.x - ny / tk) + ' ' + Math.round(pe.y + nx / tk) + - ' ' + Math.round(pe.x - nx / 2) + ' ' + Math.round(pe.y - ny / 2) + - ' ' + Math.round(pe.x + ny / tk) + ' ' + Math.round(pe.y - nx / tk) + - ' x e'; - node.setAttribute('strokeweight', (strokewidth * scale) + 'px'); - } - else - { - node.setAttribute('d', 'M ' + (pe.x + nx / 2) + ' ' + (pe.y + ny / 2) + - ' L ' + (pe.x - ny / tk) + ' ' + (pe.y + nx / tk) + - ' L ' + (pe.x - nx / 2) + ' ' + (pe.y - ny / 2) + - ' L ' + (pe.x + ny / tk) + ' ' + (pe.y - nx / tk) + - ' z'); - node.setAttribute('stroke-width', strokewidth * scale); - } - - return new mxPoint(-endOffsetX - nx, -endOffsetY - ny); - }; - - mxMarker.markers[mxConstants.ARROW_DIAMOND] = tmp_diamond; - mxMarker.markers[mxConstants.ARROW_DIAMOND_THIN] = tmp_diamond; - }()); diff --git a/src/js/shape/mxPolyline.js b/src/js/shape/mxPolyline.js deleted file mode 100644 index 2d64323..0000000 --- a/src/js/shape/mxPolyline.js +++ /dev/null @@ -1,146 +0,0 @@ -/** - * $Id: mxPolyline.js,v 1.31 2012-05-24 12:00:45 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxPolyline - * - * Extends <mxShape> to implement a polyline (a line with multiple points). - * This shape is registered under <mxConstants.SHAPE_POLYLINE> in - * <mxCellRenderer>. - * - * Constructor: mxPolyline - * - * Constructs a new polyline shape. - * - * Parameters: - * - * points - Array of <mxPoints> that define the points. This is stored in - * <mxShape.points>. - * stroke - String that defines the stroke color. Default is 'black'. This is - * stored in <stroke>. - * strokewidth - Optional integer that defines the stroke width. Default is - * 1. This is stored in <strokewidth>. - */ -function mxPolyline(points, stroke, strokewidth) -{ - this.points = points; - this.stroke = stroke; - this.strokewidth = (strokewidth != null) ? strokewidth : 1; -}; - -/** - * Extends mxShape. - */ -mxPolyline.prototype = new mxShape(); -mxPolyline.prototype.constructor = mxPolyline; - -/** - * Variable: addPipe - * - * Specifies if a SVG path should be created around any path to increase the - * tolerance for mouse events. Default is false since this shape is filled. - */ -mxPolyline.prototype.addPipe = true; - -/** - * Function: create - * - * Override to create HTML regardless of gradient and - * rounded property. - */ -mxPolyline.prototype.create = function() -{ - var node = null; - - if (this.dialect == mxConstants.DIALECT_SVG) - { - node = this.createSvg(); - } - else if (this.dialect == mxConstants.DIALECT_STRICTHTML || - (this.dialect == mxConstants.DIALECT_PREFERHTML && - this.points != null && this.points.length > 0)) - { - node = document.createElement('DIV'); - this.configureHtmlShape(node); - node.style.borderStyle = ''; - node.style.background = ''; - } - else - { - node = document.createElement('v:shape'); - this.configureVmlShape(node); - var strokeNode = document.createElement('v:stroke'); - - if (this.opacity != null) - { - strokeNode.opacity = this.opacity + '%'; - } - - node.appendChild(strokeNode); - } - - return node; -}; - -/** - * Function: redrawVml - * - * Overrides the method to update the bounds if they have not been - * assigned. - */ -mxPolyline.prototype.redrawVml = function() -{ - // Updates the bounds based on the points - if (this.points != null && this.points.length > 0 && this.points[0] != null) - { - this.bounds = new mxRectangle(this.points[0].x,this.points[0].y, 0, 0); - - for (var i = 1; i < this.points.length; i++) - { - this.bounds.add(new mxRectangle(this.points[i].x,this.points[i].y, 0, 0)); - } - } - - mxShape.prototype.redrawVml.apply(this, arguments); -}; - -/** - * Function: createSvg - * - * Creates and returns the SVG node(s) to represent this shape. - */ -mxPolyline.prototype.createSvg = function() -{ - var g = this.createSvgGroup('path'); - - // Creates an invisible shape around the path for easier - // selection with the mouse. Note: Firefox does not ignore - // the value of the stroke attribute for pointer-events: stroke, - // it does, however, ignore the visibility attribute. - if (this.addPipe) - { - this.pipe = this.createSvgPipe(); - g.appendChild(this.pipe); - } - - return g; -}; - -/** - * Function: redrawSvg - * - * Updates the SVG node(s) to reflect the latest bounds and scale. - */ -mxPolyline.prototype.redrawSvg = function() -{ - this.updateSvgShape(this.innerNode); - var d = this.innerNode.getAttribute('d'); - - if (d != null && this.pipe != null) - { - this.pipe.setAttribute('d', d); - var strokeWidth = Math.round(Math.max(1, this.strokewidth * this.scale)); - this.pipe.setAttribute('stroke-width', strokeWidth + mxShape.prototype.SVG_STROKE_TOLERANCE); - } -}; diff --git a/src/js/shape/mxRectangleShape.js b/src/js/shape/mxRectangleShape.js deleted file mode 100644 index 26688c3..0000000 --- a/src/js/shape/mxRectangleShape.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * $Id: mxRectangleShape.js,v 1.17 2012-09-26 07:51:29 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxRectangleShape - * - * Extends <mxShape> to implement a rectangle shape. - * This shape is registered under <mxConstants.SHAPE_RECTANGLE> - * in <mxCellRenderer>. - * - * Constructor: mxRectangleShape - * - * Constructs a new rectangle shape. - * - * Parameters: - * - * bounds - <mxRectangle> that defines the bounds. This is stored in - * <mxShape.bounds>. - * fill - String that defines the fill color. This is stored in <fill>. - * stroke - String that defines the stroke color. This is stored in <stroke>. - * strokewidth - Optional integer that defines the stroke width. Default is - * 1. This is stored in <strokewidth>. - */ -function mxRectangleShape(bounds, fill, stroke, strokewidth) -{ - this.bounds = bounds; - this.fill = fill; - this.stroke = stroke; - this.strokewidth = (strokewidth != null) ? strokewidth : 1; -}; - -/** - * Extends mxShape. - */ -mxRectangleShape.prototype = new mxShape(); -mxRectangleShape.prototype.constructor = mxRectangleShape; - -/** - * Function: createVml - * - * Creates and returns the VML node to represent this shape. - */ -mxRectangleShape.prototype.createVml = function() -{ - var name = (this.isRounded) ? 'v:roundrect' : 'v:rect'; - var node = document.createElement(name); - this.configureVmlShape(node); - - return node; -}; - -/** - * Function: createSvg - * - * Creates and returns the SVG node to represent this shape. - */ -mxRectangleShape.prototype.createSvg = function() -{ - return this.createSvgGroup('rect'); -}; diff --git a/src/js/shape/mxRhombus.js b/src/js/shape/mxRhombus.js deleted file mode 100644 index 37e35ec..0000000 --- a/src/js/shape/mxRhombus.js +++ /dev/null @@ -1,172 +0,0 @@ -/** - * $Id: mxRhombus.js,v 1.25 2012-04-04 07:34:50 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxRhombus - * - * Extends <mxShape> to implement a rhombus (aka diamond) shape. - * This shape is registered under <mxConstants.SHAPE_RHOMBUS> - * in <mxCellRenderer>. - * - * Constructor: mxRhombus - * - * Constructs a new rhombus shape. - * - * Parameters: - * - * bounds - <mxRectangle> that defines the bounds. This is stored in - * <mxShape.bounds>. - * fill - String that defines the fill color. This is stored in <fill>. - * stroke - String that defines the stroke color. This is stored in <stroke>. - * strokewidth - Optional integer that defines the stroke width. Default is - * 1. This is stored in <strokewidth>. - */ -function mxRhombus(bounds, fill, stroke, strokewidth) -{ - this.bounds = bounds; - this.fill = fill; - this.stroke = stroke; - this.strokewidth = (strokewidth != null) ? strokewidth : 1; -}; - -/** - * Extends mxShape. - */ -mxRhombus.prototype = new mxShape(); -mxRhombus.prototype.constructor = mxRhombus; - -/** - * Variable: mixedModeHtml - * - * Overrides the parent value with false, meaning it will - * draw in VML in mixed Html mode. - */ -mxRhombus.prototype.mixedModeHtml = false; - -/** - * Variable: preferModeHtml - * - * Overrides the parent value with false, meaning it will - * draw as VML in prefer Html mode. - */ -mxRhombus.prototype.preferModeHtml = false; - -/** - * Function: createHtml - * - * Creates and returns the HTML node to represent this shape. - */ -mxRhombus.prototype.createHtml = function() -{ - var node = document.createElement('DIV'); - this.configureHtmlShape(node); - - return node; -}; - -/** - * Function: createVml - * - * Creates and returns the VML node(s) to represent this shape. - */ -mxRhombus.prototype.createVml = function() -{ - var node = document.createElement('v:shape'); - this.configureVmlShape(node); - - return node; -}; - -/** - * Function: createSvg - * - * Creates and returns the SVG node(s) to represent this shape. - */ -mxRhombus.prototype.createSvg = function() -{ - return this.createSvgGroup('path'); -}; - -// TODO: When used as an indicator, this.node.points is null -// so we use a path object for building general diamonds. -//mxRhombus.prototype.redraw = function() { -// this.node.setAttribute('strokeweight', (this.strokewidth * this.scale) + 'px'); -// var x = this.bounds.x; -// var y = this.bounds.y; -// var w = this.bounds.width; -// var h = this.bounds.height; -// this.node.points.value = (x+w/2)+','+y+' '+(x+w)+','+(y+h/2)+ -// ' '+(x+w/2)+','+(y+h)+' '+x+','+(y+h/2)+' '+ -// (x+w/2)+','+y; -//} - -/** - * Function: redrawVml - * - * Updates the VML node(s) to reflect the latest bounds and scale. - */ -mxRhombus.prototype.redrawVml = function() -{ - this.updateVmlShape(this.node); - var x = 0; - var y = 0; - var w = Math.round(this.bounds.width); - var h = Math.round(this.bounds.height); - - this.node.path = 'm ' + Math.round(x + w / 2) + ' ' + y + - ' l ' + (x + w) + ' ' + Math.round(y + h / 2) + - ' l ' + Math.round(x + w / 2) + ' ' + (y + h) + - ' l ' + x + ' ' + Math.round(y + h / 2) + ' x e'; -}; - -/** - * Function: redrawHtml - * - * Updates the HTML node(s) to reflect the latest bounds and scale. - */ -mxRhombus.prototype.redrawHtml = function() -{ - this.updateHtmlShape(this.node); -}; - -/** - * Function: redrawSvg - * - * Updates the SVG node(s) to reflect the latest bounds and scale. - */ -mxRhombus.prototype.redrawSvg = function() -{ - this.updateSvgNode(this.innerNode); - - if (this.shadowNode != null) - { - this.updateSvgNode(this.shadowNode); - } -}; - -/** - * Function: createSvgSpan - * - * Updates the path for the given SVG node. - */ -mxRhombus.prototype.updateSvgNode = function(node) -{ - var strokeWidth = Math.round(Math.max(1, this.strokewidth * this.scale)); - node.setAttribute('stroke-width', strokeWidth); - var x = this.bounds.x; - var y = this.bounds.y; - var w = this.bounds.width; - var h = this.bounds.height; - var d = 'M ' + Math.round(x + w / 2) + ' ' + Math.round(y) + ' L ' + Math.round(x + w) + ' ' + Math.round(y + h / 2) + - ' L ' + Math.round(x + w / 2) + ' ' + Math.round(y + h) + ' L ' + Math.round(x) + ' ' + Math.round(y + h / 2) + - ' Z '; - node.setAttribute('d', d); - this.updateSvgTransform(node, node == this.shadowNode); - - if (this.isDashed) - { - var phase = Math.max(1, Math.round(3 * this.scale * this.strokewidth)); - node.setAttribute('stroke-dasharray', phase + ' ' + phase); - } -}; diff --git a/src/js/shape/mxShape.js b/src/js/shape/mxShape.js deleted file mode 100644 index 44ba3e7..0000000 --- a/src/js/shape/mxShape.js +++ /dev/null @@ -1,2045 +0,0 @@ -/** - * $Id: mxShape.js,v 1.173 2012-07-31 11:46:53 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxShape - * - * Base class for all shapes. A shape in mxGraph is a - * separate implementation for SVG, VML and HTML. Which - * implementation to use is controlled by the <dialect> - * property which is assigned from within the <mxCellRenderer> - * when the shape is created. The dialect must be assigned - * for a shape, and it does normally depend on the browser and - * the confiuration of the graph (see <mxGraph> rendering hint). - * - * For each supported shape in SVG and VML, a corresponding - * shape exists in mxGraph, namely for text, image, rectangle, - * rhombus, ellipse and polyline. The other shapes are a - * combination of these shapes (eg. label and swimlane) - * or they consist of one or more (filled) path objects - * (eg. actor and cylinder). The HTML implementation is - * optional but may be required for a HTML-only view of - * the graph. - * - * Custom Shapes: - * - * To extend from this class, the basic code looks as follows. - * In the special case where the custom shape consists only of - * one filled region or one filled region and an additional stroke - * the <mxActor> and <mxCylinder> should be subclassed, - * respectively. These implement <redrawPath> in order to create - * the path expression for VML and SVG via a unified API (see - * <mxPath>). <mxCylinder.redrawPath> has an additional boolean - * argument to draw the foreground and background separately. - * - * (code) - * function CustomShape() { } - * - * CustomShape.prototype = new mxShape(); - * CustomShape.prototype.constructor = CustomShape; - * (end) - * - * To register a custom shape in an existing graph instance, - * one must register the shape under a new name in the graph's - * cell renderer as follows: - * - * (code) - * graph.cellRenderer.registerShape('customShape', CustomShape); - * (end) - * - * The second argument is the name of the constructor. - * - * In order to use the shape you can refer to the given name above - * in a stylesheet. For example, to change the shape for the default - * vertex style, the following code is used: - * - * (code) - * var style = graph.getStylesheet().getDefaultVertexStyle(); - * style[mxConstants.STYLE_SHAPE] = 'customShape'; - * (end) - * - * Constructor: mxShape - * - * Constructs a new shape. - */ -function mxShape() { }; - -/** - * Variable: SVG_STROKE_TOLERANCE - * - * Event-tolerance for SVG strokes (in px). Default is 8. - */ -mxShape.prototype.SVG_STROKE_TOLERANCE = 8; - -/** - * Variable: scale - * - * Holds the scale in which the shape is being painted. - */ -mxShape.prototype.scale = 1; - -/** - * Variable: dialect - * - * Holds the dialect in which the shape is to be painted. - * This can be one of the DIALECT constants in <mxConstants>. - */ -mxShape.prototype.dialect = null; - -/** - * Variable: crisp - * - * Special attribute for SVG rendering to set the shape-rendering attribute to - * crispEdges in the output. This is ignored in IE. Default is false. To - * disable antialias in IE, the explorer.css file can be changed as follows: - * - * [code] - * v\:* { - * behavior: url(#default#VML); - * antialias: false; - * } - * [/code] - */ -mxShape.prototype.crisp = false; - -/** - * Variable: roundedCrispSvg - * - * Specifies if crisp rendering should be enabled for rounded shapes. - * Default is true. - */ -mxShape.prototype.roundedCrispSvg = true; - -/** - * Variable: mixedModeHtml - * - * Specifies if <createHtml> should be used in mixed Html mode. - * Default is true. - */ -mxShape.prototype.mixedModeHtml = true; - -/** - * Variable: preferModeHtml - * - * Specifies if <createHtml> should be used in prefer Html mode. - * Default is true. - */ -mxShape.prototype.preferModeHtml = true; - -/** - * Variable: bounds - * - * Holds the <mxRectangle> that specifies the bounds of this shape. - */ -mxShape.prototype.bounds = null; - -/** - * Variable: points - * - * Holds the array of <mxPoints> that specify the points of this shape. - */ -mxShape.prototype.points = null; - -/** - * Variable: node - * - * Holds the outermost DOM node that represents this shape. - */ -mxShape.prototype.node = null; - -/** - * Variable: label - * - * Reference to the DOM node that should contain the label. This is null - * if the label should be placed inside <node> or <innerNode>. - */ -mxShape.prototype.label = null; - -/** - * Variable: innerNode - * - * Holds the DOM node that graphically represents this shape. This may be - * null if the outermost DOM <node> represents this shape. - */ -mxShape.prototype.innerNode = null; - -/** - * Variable: style - * - * Holds the style of the cell state that corresponds to this shape. This may - * be null if the shape is used directly, without a cell state. - */ -mxShape.prototype.style = null; - -/** - * Variable: startOffset - * - * Specifies the offset in pixels from the first point in <points> and - * the actual start of the shape. - */ -mxShape.prototype.startOffset = null; - -/** - * Variable: endOffset - * - * Specifies the offset in pixels from the last point in <points> and - * the actual start of the shape. - */ -mxShape.prototype.endOffset = null; - -/** - * Variable: boundingBox - * - * Contains the bounding box of the shape, that is, the smallest rectangle - * that includes all pixels of the shape. - */ -mxShape.prototype.boundingBox = null; - -/** - * Variable: vmlNodes - * - * Array if VML node names to fix in IE8 standards mode. - */ -mxShape.prototype.vmlNodes = ['node', 'strokeNode', 'fillNode', 'shadowNode']; - -/** - * Variable: vmlScale - * - * Internal scaling for VML using coordsize for better precision. - */ -mxShape.prototype.vmlScale = 1; - -/** - * Variable: strokewidth - * - * Holds the current strokewidth. Default is 1. - */ -mxShape.prototype.strokewidth = 1; - -/** - * Function: setCursor - * - * Sets the cursor on the given shape. - * - * Parameters: - * - * cursor - The cursor to be used. - */ -mxShape.prototype.setCursor = function(cursor) -{ - if (cursor == null) - { - cursor = ''; - } - - this.cursor = cursor; - - if (this.innerNode != null) - { - this.innerNode.style.cursor = cursor; - } - - if (this.node != null) - { - this.node.style.cursor = cursor; - } - - if (this.pipe != null) - { - this.pipe.style.cursor = cursor; - } -}; - -/** - * Function: getCursor - * - * Returns the current cursor. - */ -mxShape.prototype.getCursor = function() -{ - return this.cursor; -}; - -/** - * Function: init - * - * Initializes the shape by creaing the DOM node using <create> - * and adding it into the given container. - * - * Parameters: - * - * container - DOM node that will contain the shape. - */ -mxShape.prototype.init = function(container) -{ - if (this.node == null) - { - this.node = this.create(container); - - if (container != null) - { - container.appendChild(this.node); - - // Workaround for broken VML in IE8 standards mode. This gives an ID to - // each element that is referenced from this instance. After adding the - // DOM to the document, the outerHTML is overwritten to fix the VML - // rendering and the references are restored. - if (document.documentMode == 8 && mxUtils.isVml(this.node)) - { - this.reparseVml(); - } - } - } - - // Gradients are inserted late when the owner SVG element is known - if (this.insertGradientNode != null) - { - this.insertGradient(this.insertGradientNode); - this.insertGradientNode = null; - } -}; - -/** - * Function: reparseVml - * - * Forces a parsing of the outerHTML of this node and restores all references specified in <vmlNodes>. - * This is a workaround for the VML rendering bug in IE8 standards mode. - */ -mxShape.prototype.reparseVml = function() -{ - // Assigns temporary IDs to VML nodes so that references can be restored when - // inserted into the DOM as a string - for (var i = 0; i < this.vmlNodes.length; i++) - { - if (this[this.vmlNodes[i]] != null) - { - this[this.vmlNodes[i]].setAttribute('id', 'mxTemporaryReference-' + this.vmlNodes[i]); - } - } - - this.node.outerHTML = this.node.outerHTML; - - // Restores references to the actual DOM nodes - for (var i = 0; i < this.vmlNodes.length; i++) - { - if (this[this.vmlNodes[i]] != null) - { - this[this.vmlNodes[i]] = this.node.ownerDocument.getElementById('mxTemporaryReference-' + this.vmlNodes[i]); - this[this.vmlNodes[i]].removeAttribute('id'); - } - } -}; - -/** - * Function: insertGradient - * - * Inserts the given gradient node. - */ -mxShape.prototype.insertGradient = function(node) -{ - // Gradients are inserted late when the owner SVG element is known - if (node != null) - { - // Checks if the given gradient already exists inside the SVG element - // that also contains the node that represents this shape. If the gradient - // with the same ID exists in another SVG element, then this will add - // a copy of the gradient with a different ID to the SVG element and update - // the reference accordingly. This is required in Firefox because if the - // referenced fill element is removed from the DOM the shape appears black. - var count = 0; - var id = node.getAttribute('id'); - var gradient = document.getElementById(id); - - while (gradient != null && gradient.ownerSVGElement != this.node.ownerSVGElement) - { - count++; - id = node.getAttribute('id') + '-' + count; - gradient = document.getElementById(id); - } - - // According to specification, gradients should be put in a defs - // section in the first child of the owner SVG element. However, - // it turns out that gradients only work when added as follows. - if (gradient == null) - { - node.setAttribute('id', id); - this.node.ownerSVGElement.appendChild(node); - gradient = node; - } - - if (gradient != null) - { - var ref = 'url(#' + id + ')'; - var tmp = (this.innerNode != null) ? this.innerNode : this.node; - - if (tmp != null && tmp.getAttribute('fill') != ref) - { - tmp.setAttribute('fill', ref); - } - } - } -}; - -/** - * Function: isMixedModeHtml - * - * Used to determine if a shape can be rendered using <createHtml> in mixed - * mode Html without compromising the display accuracy. The default - * implementation will check if the shape is not rounded or rotated and has - * no gradient, and will use a DIV if that is the case. It will also check - * if <mxShape.mixedModeHtml> is true, which is the default settings. - * Subclassers can either override <mixedModeHtml> or this function if the - * result depends on dynamic values. The graph's dialect is available via - * <dialect>. - */ -mxShape.prototype.isMixedModeHtml = function() -{ - return this.mixedModeHtml && !this.isRounded && !this.isShadow && this.gradient == null && - mxUtils.getValue(this.style, mxConstants.STYLE_GLASS, 0) == 0 && - mxUtils.getValue(this.style, mxConstants.STYLE_ROTATION, 0) == 0; -}; - -/** - * Function: create - * - * Creates and returns the DOM node(s) for the shape in - * the given container. This implementation invokes - * <createSvg>, <createHtml> or <createVml> depending - * on the <dialect> and style settings. - * - * Parameters: - * - * container - DOM node that will contain the shape. - */ -mxShape.prototype.create = function(container) -{ - var node = null; - - if (this.dialect == mxConstants.DIALECT_SVG) - { - node = this.createSvg(); - } - else if (this.dialect == mxConstants.DIALECT_STRICTHTML || - (this.preferModeHtml && this.dialect == mxConstants.DIALECT_PREFERHTML) || - (this.isMixedModeHtml() && this.dialect == mxConstants.DIALECT_MIXEDHTML)) - { - node = this.createHtml(); - } - else - { - node = this.createVml(); - } - - return node; -}; - -/** - * Function: createHtml - * - * Creates and returns the HTML DOM node(s) to represent - * this shape. This implementation falls back to <createVml> - * so that the HTML creation is optional. - */ -mxShape.prototype.createHtml = function() -{ - var node = document.createElement('DIV'); - this.configureHtmlShape(node); - - return node; -}; - -/** - * Function: destroy - * - * Destroys the shape by removing it from the DOM and releasing the DOM - * node associated with the shape using <mxEvent.release>. - */ -mxShape.prototype.destroy = function() -{ - if (this.node != null) - { - mxEvent.release(this.node); - - if (this.node.parentNode != null) - { - this.node.parentNode.removeChild(this.node); - } - - if (this.node.glassOverlay) - { - this.node.glassOverlay.parentNode.removeChild(this.node.glassOverlay); - this.node.glassOverlay = null; - } - - this.node = null; - } -}; - -/** - * Function: apply - * - * Applies the style of the given <mxCellState> to the shape. This - * implementation assigns the following styles to local fields: - * - * - <mxConstants.STYLE_FILLCOLOR> => fill - * - <mxConstants.STYLE_GRADIENTCOLOR> => gradient - * - <mxConstants.STYLE_GRADIENT_DIRECTION> => gradientDirection - * - <mxConstants.STYLE_OPACITY> => opacity - * - <mxConstants.STYLE_STROKECOLOR> => stroke - * - <mxConstants.STYLE_STROKEWIDTH> => strokewidth - * - <mxConstants.STYLE_SHADOW> => isShadow - * - <mxConstants.STYLE_DASHED> => isDashed - * - <mxConstants.STYLE_SPACING> => spacing - * - <mxConstants.STYLE_STARTSIZE> => startSize - * - <mxConstants.STYLE_ENDSIZE> => endSize - * - <mxConstants.STYLE_ROUNDED> => isRounded - * - <mxConstants.STYLE_STARTARROW> => startArrow - * - <mxConstants.STYLE_ENDARROW> => endArrow - * - <mxConstants.STYLE_ROTATION> => rotation - * - <mxConstants.STYLE_DIRECTION> => direction - * - * This keeps a reference to the <style>. If you need to keep a reference to - * the cell, you can override this method and store a local reference to - * state.cell or the <mxCellState> itself. - * - * Parameters: - * - * state - <mxCellState> of the corresponding cell. - */ -mxShape.prototype.apply = function(state) -{ - var style = state.style; - this.style = style; - - if (style != null) - { - this.fill = mxUtils.getValue(style, mxConstants.STYLE_FILLCOLOR, this.fill); - this.gradient = mxUtils.getValue(style, mxConstants.STYLE_GRADIENTCOLOR, this.gradient); - this.gradientDirection = mxUtils.getValue(style, mxConstants.STYLE_GRADIENT_DIRECTION, this.gradientDirection); - this.opacity = mxUtils.getValue(style, mxConstants.STYLE_OPACITY, this.opacity); - this.stroke = mxUtils.getValue(style, mxConstants.STYLE_STROKECOLOR, this.stroke); - this.strokewidth = mxUtils.getNumber(style, mxConstants.STYLE_STROKEWIDTH, this.strokewidth); - this.isShadow = mxUtils.getValue(style, mxConstants.STYLE_SHADOW, this.isShadow); - this.isDashed = mxUtils.getValue(style, mxConstants.STYLE_DASHED, this.isDashed); - this.spacing = mxUtils.getValue(style, mxConstants.STYLE_SPACING, this.spacing); - this.startSize = mxUtils.getNumber(style, mxConstants.STYLE_STARTSIZE, this.startSize); - this.endSize = mxUtils.getNumber(style, mxConstants.STYLE_ENDSIZE, this.endSize); - this.isRounded = mxUtils.getValue(style, mxConstants.STYLE_ROUNDED, this.isRounded); - this.startArrow = mxUtils.getValue(style, mxConstants.STYLE_STARTARROW, this.startArrow); - this.endArrow = mxUtils.getValue(style, mxConstants.STYLE_ENDARROW, this.endArrow); - this.rotation = mxUtils.getValue(style, mxConstants.STYLE_ROTATION, this.rotation); - this.direction = mxUtils.getValue(style, mxConstants.STYLE_DIRECTION, this.direction); - - if (this.fill == 'none') - { - this.fill = null; - } - - if (this.gradient == 'none') - { - this.gradient = null; - } - - if (this.stroke == 'none') - { - this.stroke = null; - } - } -}; - -/** - * Function: createSvgGroup - * - * Creates a SVG group element and adds the given shape as a child of the - * element. The child is stored in <innerNode> for later access. - */ -mxShape.prototype.createSvgGroup = function(shape) -{ - var g = document.createElementNS(mxConstants.NS_SVG, 'g'); - - // Creates the shape inside an svg group - this.innerNode = document.createElementNS(mxConstants.NS_SVG, shape); - this.configureSvgShape(this.innerNode); - - // Avoids anti-aliasing for non-rounded rectangles with a - // strokewidth of 1 or more pixels - if (shape == 'rect' && this.strokewidth * this.scale >= 1 && !this.isRounded) - { - this.innerNode.setAttribute('shape-rendering', 'optimizeSpeed'); - } - - // Creates the shadow - this.shadowNode = this.createSvgShadow(this.innerNode); - - if (this.shadowNode != null) - { - g.appendChild(this.shadowNode); - } - - // Appends the main shape after the shadow - g.appendChild(this.innerNode); - - return g; -}; - -/** - * Function: createSvgShadow - * - * Creates a clone of the given node and configures the node's color - * to use <mxConstants.SHADOWCOLOR>. - */ -mxShape.prototype.createSvgShadow = function(node) -{ - if (this.isShadow) - { - var shadow = node.cloneNode(true); - shadow.setAttribute('opacity', mxConstants.SHADOW_OPACITY); - - if (this.fill != null && this.fill != mxConstants.NONE) - { - shadow.setAttribute('fill', mxConstants.SHADOWCOLOR); - } - - if (this.stroke != null && this.stroke != mxConstants.NONE) - { - shadow.setAttribute('stroke', mxConstants.SHADOWCOLOR); - } - - return shadow; - } - - return null; -}; - -/** - * Function: configureHtmlShape - * - * Configures the specified HTML node by applying the current color, - * bounds, shadow, opacity etc. - */ -mxShape.prototype.configureHtmlShape = function(node) -{ - if (mxUtils.isVml(node)) - { - this.configureVmlShape(node); - } - else - { - node.style.position = 'absolute'; - node.style.overflow = 'hidden'; - var color = this.stroke; - - if (color != null && color != mxConstants.NONE) - { - node.style.borderColor = color; - - if (this.isDashed) - { - node.style.borderStyle = 'dashed'; - } - else if (this.strokewidth > 0) - { - node.style.borderStyle = 'solid'; - } - - node.style.borderWidth = Math.ceil(this.strokewidth * this.scale) + 'px'; - } - else - { - node.style.borderWidth = '0px'; - } - - color = this.fill; - node.style.background = ''; - - if (color != null && color != mxConstants.NONE) - { - node.style.backgroundColor = color; - } - else if (this.points == null) - { - this.configureTransparentBackground(node); - } - - if (this.opacity != null) - { - mxUtils.setOpacity(node, this.opacity); - } - } -}; - -/** - * Function: updateVmlFill - * - * Updates the given VML fill node. - */ -mxShape.prototype.updateVmlFill = function(node, c1, c2, dir, alpha) -{ - node.color = c1; - - if (alpha != null && alpha != 100) - { - node.opacity = alpha + '%'; - - if (c2 != null) - { - // LATER: Set namespaced attribute without using setAttribute - // which is required for updating the value in IE8 standards. - node.setAttribute('o:opacity2', alpha + '%'); - } - } - - if (c2 != null) - { - node.type = 'gradient'; - node.color2 = c2; - var angle = '180'; - - if (this.gradientDirection == mxConstants.DIRECTION_EAST) - { - angle = '270'; - } - else if (this.gradientDirection == mxConstants.DIRECTION_WEST) - { - angle = '90'; - } - else if (this.gradientDirection == mxConstants.DIRECTION_NORTH) - { - angle = '0'; - } - - node.angle = angle; - } -}; - -/** - * Function: updateVmlStrokeNode - * - * Creates the stroke node for VML. - */ -mxShape.prototype.updateVmlStrokeNode = function(parent) -{ - // Stroke node is always needed to specify defaults that match SVG output - if (this.strokeNode == null) - { - this.strokeNode = document.createElement('v:stroke'); - - // To math SVG defaults jointsyle miter and miterlimit 4 - this.strokeNode.joinstyle = 'miter'; - this.strokeNode.miterlimit = 4; - - parent.appendChild(this.strokeNode); - } - - if (this.opacity != null) - { - this.strokeNode.opacity = this.opacity + '%'; - } - - this.updateVmlDashStyle(); -}; - -/** - * Function: updateVmlStrokeColor - * - * Updates the VML stroke color for the given node. - */ -mxShape.prototype.updateVmlStrokeColor = function(node) -{ - var color = this.stroke; - - if (color != null && color != mxConstants.NONE) - { - node.stroked = 'true'; - node.strokecolor = color; - } - else - { - node.stroked = 'false'; - } -}; - -/** - * Function: configureVmlShape - * - * Configures the specified VML node by applying the current color, - * bounds, shadow, opacity etc. - */ -mxShape.prototype.configureVmlShape = function(node) -{ - node.style.position = 'absolute'; - this.updateVmlStrokeColor(node); - node.style.background = ''; - var color = this.fill; - - if (color != null && color != mxConstants.NONE) - { - if (this.fillNode == null) - { - this.fillNode = document.createElement('v:fill'); - node.appendChild(this.fillNode); - } - - this.updateVmlFill(this.fillNode, color, this.gradient, this.gradientDirection, this.opacity); - } - else - { - node.filled = 'false'; - - if (this.points == null) - { - this.configureTransparentBackground(node); - } - } - - this.updateVmlStrokeNode(node); - - if (this.isShadow) - { - this.createVmlShadow(node); - } - - // Fixes possible hang in IE when arcsize is set on non-rects - if (node.nodeName == 'roundrect') - { - // Workaround for occasional "member not found" error - try - { - var f = mxConstants.RECTANGLE_ROUNDING_FACTOR * 100; - - if (this.style != null) - { - f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, f); - } - - node.setAttribute('arcsize', String(f) + '%'); - } - catch (e) - { - // ignore - } - } -}; - -/** - * Function: createVmlShadow - * - * Creates the VML shadow node. - */ -mxShape.prototype.createVmlShadow = function(node) -{ - // Adds a shadow only once per shape - if (this.shadowNode == null) - { - this.shadowNode = document.createElement('v:shadow'); - this.shadowNode.on = 'true'; - this.shadowNode.color = mxConstants.SHADOWCOLOR; - this.shadowNode.opacity = (mxConstants.SHADOW_OPACITY * 100) + '%'; - - this.shadowStrokeNode = document.createElement('v:stroke'); - this.shadowNode.appendChild(this.shadowStrokeNode); - - node.appendChild(this.shadowNode); - } -}; - -/** - * Function: configureTransparentBackground - * - * Hook to make the background of a shape transparent. This hook was added as - * a workaround for the "display non secure items" warning dialog in IE which - * appears if the background:url(transparent.gif) is used in the overlay pane - * of a diagram. Since only mxImageShapes currently exist in the overlay pane - * this function is only overridden in mxImageShape. - */ -mxShape.prototype.configureTransparentBackground = function(node) -{ - node.style.background = 'url(\'' + mxClient.imageBasePath + '/transparent.gif\')'; -}; - -/** - * Function: configureSvgShape - * - * Configures the specified SVG node by applying the current color, - * bounds, shadow, opacity etc. - */ -mxShape.prototype.configureSvgShape = function(node) -{ - var color = this.stroke; - - if (color != null && color != mxConstants.NONE) - { - node.setAttribute('stroke', color); - } - else - { - node.setAttribute('stroke', 'none'); - } - - color = this.fill; - - if (color != null && color != mxConstants.NONE) - { - // Fetches a reference to a shared gradient - if (this.gradient != null) - { - var id = this.getGradientId(color, this.gradient); - - if (this.gradientNode != null && this.gradientNode.getAttribute('id') != id) - { - this.gradientNode = null; - node.setAttribute('fill', ''); - } - - if (this.gradientNode == null) - { - this.gradientNode = this.createSvgGradient(id, - color, this.gradient, node); - node.setAttribute('fill', 'url(#'+id+')'); - } - } - else - { - // TODO: Remove gradient from document if no longer shared - this.gradientNode = null; - node.setAttribute('fill', color); - } - } - else - { - node.setAttribute('fill', 'none'); - } - - if (this.opacity != null) - { - // Improves opacity performance in Firefox - node.setAttribute('fill-opacity', this.opacity / 100); - node.setAttribute('stroke-opacity', this.opacity / 100); - } -}; - -/** - * Function: getGradientId - * - * Creates a unique ID for the gradient of this shape. - */ -mxShape.prototype.getGradientId = function(start, end) -{ - // Removes illegal characters from gradient ID - if (start.charAt(0) == '#') - { - start = start.substring(1); - } - - if (end.charAt(0) == '#') - { - end = end.substring(1); - } - - // Workaround for gradient IDs not working in Safari 5 / Chrome 6 - // if they contain uppercase characters - start = start.toLowerCase(); - end = end.toLowerCase(); - - var dir = null; - - if (this.gradientDirection == null || - this.gradientDirection == mxConstants.DIRECTION_SOUTH) - { - dir = 'south'; - } - else if (this.gradientDirection == mxConstants.DIRECTION_EAST) - { - dir = 'east'; - } - else - { - var tmp = start; - start = end; - end = tmp; - - if (this.gradientDirection == mxConstants.DIRECTION_NORTH) - { - dir = 'south'; - } - else if (this.gradientDirection == mxConstants.DIRECTION_WEST) - { - dir = 'east'; - } - } - - return 'mx-gradient-'+start+'-'+end+'-'+dir; -}; - -/** - * Function: createSvgPipe - * - * Creates an invisible path which is used to increase the hit detection for - * edges in SVG. - */ -mxShape.prototype.createSvgPipe = function(id, start, end, node) -{ - var pipe = document.createElementNS(mxConstants.NS_SVG, 'path'); - pipe.setAttribute('pointer-events', 'stroke'); - pipe.setAttribute('fill', 'none'); - pipe.setAttribute('visibility', 'hidden'); - // Workaround for Opera ignoring the visiblity attribute above while - // other browsers need a stroke color to perform the hit-detection but - // do not ignore the visibility attribute. Side-effect is that Opera's - // hit detection for horizontal/vertical edges seems to ignore the pipe. - pipe.setAttribute('stroke', (mxClient.IS_OP) ? 'none' : 'white'); - - return pipe; -}; - -/** - * Function: createSvgGradient - * - * Creates a gradient object for SVG using the specified startcolor, - * endcolor and opacity. - */ -mxShape.prototype.createSvgGradient = function(id, start, end, node) -{ - var gradient = this.insertGradientNode; - - if (gradient == null) - { - gradient = document.createElementNS(mxConstants.NS_SVG, 'linearGradient'); - gradient.setAttribute('id', id); - gradient.setAttribute('x1', '0%'); - gradient.setAttribute('y1', '0%'); - gradient.setAttribute('x2', '0%'); - gradient.setAttribute('y2', '0%'); - - if (this.gradientDirection == null || - this.gradientDirection == mxConstants.DIRECTION_SOUTH) - { - gradient.setAttribute('y2', '100%'); - } - else if (this.gradientDirection == mxConstants.DIRECTION_EAST) - { - gradient.setAttribute('x2', '100%'); - } - else if (this.gradientDirection == mxConstants.DIRECTION_NORTH) - { - gradient.setAttribute('y1', '100%'); - } - else if (this.gradientDirection == mxConstants.DIRECTION_WEST) - { - gradient.setAttribute('x1', '100%'); - } - - var stop = document.createElementNS(mxConstants.NS_SVG, 'stop'); - stop.setAttribute('offset', '0%'); - stop.setAttribute('style', 'stop-color:'+start); - gradient.appendChild(stop); - - stop = document.createElementNS(mxConstants.NS_SVG, 'stop'); - stop.setAttribute('offset', '100%'); - stop.setAttribute('style', 'stop-color:'+end); - gradient.appendChild(stop); - } - - // Inserted later when the owner SVG element is known - this.insertGradientNode = gradient; - - return gradient; -}; - -/** - * Function: createPoints - * - * Creates a path expression using the specified commands for this.points. - * If <isRounded> is true, then the path contains curves for the corners. - */ -mxShape.prototype.createPoints = function(moveCmd, lineCmd, curveCmd, isRelative) -{ - var offsetX = (isRelative) ? this.bounds.x : 0; - var offsetY = (isRelative) ? this.bounds.y : 0; - - // Workaround for crisp shape-rendering in IE9 - var crisp = (this.crisp && this.dialect == mxConstants.DIALECT_SVG && mxClient.IS_IE) ? 0.5 : 0; - - if (isNaN(this.points[0].x) || isNaN(this.points[0].y)) - { - return null; - } - - var size = mxConstants.LINE_ARCSIZE * this.scale; - var p0 = this.points[0]; - - if (this.startOffset != null) - { - p0 = p0.clone(); - p0.x += this.startOffset.x; - p0.y += this.startOffset.y; - } - - var points = moveCmd + ' ' + (Math.round(p0.x - offsetX) + crisp) + ' ' + - (Math.round(p0.y - offsetY) + crisp) + ' '; - - for (var i = 1; i < this.points.length; i++) - { - p0 = this.points[i - 1]; - var pt = this.points[i]; - - if (isNaN(pt.x) || isNaN(pt.y)) - { - return null; - } - - if (i == this.points.length - 1 && this.endOffset != null) - { - pt = pt.clone(); - pt.x += this.endOffset.x; - pt.y += this.endOffset.y; - } - - var dx = p0.x - pt.x; - var dy = p0.y - pt.y; - - if ((this.isRounded && i < this.points.length - 1) && - (dx != 0 || dy != 0) && this.scale > 0.3) - { - // Draws a line from the last point to the current point with a spacing - // of size off the current point into direction of the last point - var dist = Math.sqrt(dx * dx + dy * dy); - var nx1 = dx * Math.min(size, dist / 2) / dist; - var ny1 = dy * Math.min(size, dist / 2) / dist; - points += lineCmd + ' ' + (Math.round(pt.x + nx1 - offsetX) + crisp) + ' ' + - (Math.round(pt.y + ny1 - offsetY) + crisp) + ' '; - - // Draws a curve from the last point to the current point with a spacing - // of size off the current point into direction of the next point - var pe = this.points[i+1]; - dx = pe.x - pt.x; - dy = pe.y - pt.y; - - dist = Math.max(1, Math.sqrt(dx * dx + dy * dy)); - - if (dist != 0) - { - var nx2 = dx * Math.min(size, dist / 2) / dist; - var ny2 = dy * Math.min(size, dist / 2) / dist; - - points += curveCmd + ' ' + Math.round(pt.x - offsetX) + ' '+ - Math.round(pt.y - offsetY) + ' ' + Math.round(pt.x - offsetX) + ',' + - Math.round(pt.y - offsetY) + ' ' + (Math.round(pt.x + nx2 - offsetX) + crisp) + ' ' + - (Math.round(pt.y + ny2 - offsetY) + crisp) + ' '; - } - } - else - { - points += lineCmd + ' ' + (Math.round(pt.x - offsetX) + crisp) + ' ' + (Math.round(pt.y - offsetY) + crisp) + ' '; - } - } - - return points; -}; - -/** - * Function: updateHtmlShape - * - * Updates the bounds or points of the specified HTML node and - * updates the inner children to reflect the changes. - */ -mxShape.prototype.updateHtmlShape = function(node) -{ - if (node != null) - { - if (mxUtils.isVml(node)) - { - this.updateVmlShape(node); - } - else - { - var sw = Math.ceil(this.strokewidth * this.scale); - node.style.borderWidth = Math.max(1, sw) + 'px'; - - if (this.bounds != null && !isNaN(this.bounds.x) && !isNaN(this.bounds.y) && - !isNaN(this.bounds.width) && !isNaN(this.bounds.height)) - { - node.style.left = Math.round(this.bounds.x - sw / 2) + 'px'; - node.style.top = Math.round(this.bounds.y - sw / 2) + 'px'; - - if (document.compatMode == 'CSS1Compat') - { - sw = -sw; - } - - node.style.width = Math.round(Math.max(0, this.bounds.width + sw)) + 'px'; - node.style.height = Math.round(Math.max(0, this.bounds.height + sw)) + 'px'; - - if (this.bounds.width == 0 || this.bounds.height == 0) - { - node.style.visibility = 'hidden'; - } - else - { - node.style.visibility = 'visible'; - } - } - } - - if (this.points != null && this.bounds != null && !mxUtils.isVml(node)) - { - if (this.divContainer == null) - { - this.divContainer = node; - } - - while (this.divContainer.firstChild != null) - { - mxEvent.release(this.divContainer.firstChild); - this.divContainer.removeChild(this.divContainer.firstChild); - } - - node.style.borderStyle = ''; - node.style.background = ''; - - if (this.points.length == 2) - { - var p0 = this.points[0]; - var pe = this.points[1]; - - var dx = pe.x - p0.x; - var dy = pe.y - p0.y; - - if (dx == 0 || dy == 0) - { - node.style.borderStyle = 'solid'; - } - else - { - node.style.width = Math.round(this.bounds.width + 1) + 'px'; - node.style.height = Math.round(this.bounds.height + 1) + 'px'; - - var length = Math.sqrt(dx * dx + dy * dy); - var dotCount = 1 + (length / (8 * this.scale)); - - var nx = dx / dotCount; - var ny = dy / dotCount; - var x = p0.x - this.bounds.x; - var y = p0.y - this.bounds.y; - - for (var i = 0; i < dotCount; i++) - { - var tmp = document.createElement('DIV'); - - tmp.style.position = 'absolute'; - tmp.style.overflow = 'hidden'; - - tmp.style.left = Math.round(x) + 'px'; - tmp.style.top = Math.round(y) + 'px'; - tmp.style.width = Math.max(1, 2 * this.scale) + 'px'; - tmp.style.height = Math.max(1, 2 * this.scale) + 'px'; - - tmp.style.backgroundColor = this.stroke; - this.divContainer.appendChild(tmp); - - x += nx; - y += ny; - } - } - } - else if (this.points.length == 3) - { - var mid = this.points[1]; - - var n = '0'; - var s = '1'; - var w = '0'; - var e = '1'; - - if (mid.x == this.bounds.x) - { - e = '0'; - w = '1'; - } - - if (mid.y == this.bounds.y) - { - n = '1'; - s = '0'; - } - - node.style.borderStyle = 'solid'; - node.style.borderWidth = n + ' ' + e + ' ' + s + ' ' + w + 'px'; - } - else - { - node.style.width = Math.round(this.bounds.width + 1) + 'px'; - node.style.height = Math.round(this.bounds.height + 1) + 'px'; - var last = this.points[0]; - - for (var i = 1; i < this.points.length; i++) - { - var next = this.points[i]; - - // TODO: Use one div for multiple lines - var tmp = document.createElement('DIV'); - - tmp.style.position = 'absolute'; - tmp.style.overflow = 'hidden'; - - tmp.style.borderColor = this.stroke; - tmp.style.borderStyle = 'solid'; - tmp.style.borderWidth = '1 0 0 1px'; - - var x = Math.min(next.x, last.x) - this.bounds.x; - var y = Math.min(next.y, last.y) - this.bounds.y; - var w = Math.max(1, Math.abs(next.x - last.x)); - var h = Math.max(1, Math.abs(next.y - last.y)); - - tmp.style.left = x + 'px'; - tmp.style.top = y + 'px'; - tmp.style.width = w + 'px'; - tmp.style.height = h + 'px'; - - this.divContainer.appendChild(tmp); - last = next; - } - } - } - } -}; - -/** - * Function: updateVmlDashStyle - * - * Updates the dashstyle in the stroke node. - */ -mxShape.prototype.updateVmlDashStyle = function() -{ - if (this.isDashed) - { - if (this.strokeNode.dashstyle != 'dash') - { - this.strokeNode.dashstyle = 'dash'; - } - } - else if (this.strokeNode.dashstyle != 'solid') - { - this.strokeNode.dashstyle = 'solid'; - } -}; - -/** - * Function: updateVmlShape - * - * Updates the bounds or points of the specified VML node and - * updates the inner children to reflect the changes. - */ -mxShape.prototype.updateVmlShape = function(node) -{ - node.strokeweight = (this.strokewidth * this.scale) + 'px'; - - // Dash pattern needs updating as it depends on strokeweight in VML - if (this.strokeNode != null) - { - this.updateVmlDashStyle(); - } - - // Updates the offset of the shadow - if (this.shadowNode != null) - { - var dx = Math.round(mxConstants.SHADOW_OFFSET_X * this.scale); - var dy = Math.round(mxConstants.SHADOW_OFFSET_Y * this.scale); - this.shadowNode.offset = dx + 'px,' + dy + 'px'; - } - - if (this.bounds != null && !isNaN(this.bounds.x) && !isNaN(this.bounds.y) && - !isNaN(this.bounds.width) && !isNaN(this.bounds.height)) - { - var f = 1; - - var w = Math.max(0, Math.round(this.bounds.width)); - var h = Math.max(0, Math.round(this.bounds.height)); - - // Groups and shapes need a coordsize - if (this.points != null || node.nodeName == 'shape' || node.nodeName == 'group') - { - var tmp = (node.parentNode.nodeName == 'group') ? 1 : this.vmlScale; - node.coordsize = (w * tmp) + ',' + (h * tmp); - } - else if (node.parentNode.nodeName == 'group') - { - f = this.vmlScale; - } - - // Only top-level nodes are non-relative and rotated - if (node.parentNode != this.node) - { - node.style.left = Math.round(this.bounds.x * f) + 'px'; - node.style.top = Math.round(this.bounds.y * f) + 'px'; - - if (this.points == null) - { - if (this.rotation != null && this.rotation != 0) - { - node.style.rotation = this.rotation; - } - else if (node.style.rotation != null) - { - node.style.rotation = ''; - } - } - } - - node.style.width = (w * f) + 'px'; - node.style.height = (h * f) + 'px'; - } - - if (this.points != null && node.nodeName != 'group') - { - if (node.nodeName == 'polyline' && node.points != null) - { - var points = ''; - - for (var i = 0; i < this.points.length; i++) - { - points += this.points[i].x + ',' + this.points[i].y + ' '; - } - - node.points.value = points; - - node.style.left = null; - node.style.top = null; - node.style.width = null; - node.style.height = null; - } - else if (this.bounds != null) - { - var points = this.createPoints('m', 'l', 'c', true); - - // Smooth style for VML (experimental) - if (this.style != null && this.style[mxConstants.STYLE_SMOOTH]) - { - var pts = this.points; - var n = pts.length; - - if (n > 3) - { - var x0 = this.bounds.x; - var y0 = this.bounds.y; - points = 'm ' + Math.round(pts[0].x - x0) + ' ' + Math.round(pts[0].y - y0) + ' qb'; - - for (var i = 1; i < n - 1; i++) - { - points += ' ' + Math.round(pts[i].x - x0) + ' ' + Math.round(pts[i].y - y0); - } - - points += ' nf l ' + Math.round(pts[n - 1].x - x0) + ' ' + Math.round(pts[n - 1].y - y0); - } - } - - node.path = points + ' e'; - } - } -}; - -/** - * Function: updateSvgBounds - * - * Updates the bounds of the given node using <bounds>. - */ -mxShape.prototype.updateSvgBounds = function(node) -{ - var w = this.bounds.width; - var h = this.bounds.height; - - if (this.isRounded && !(this.crisp && mxClient.IS_IE)) - { - node.setAttribute('x', this.bounds.x); - node.setAttribute('y', this.bounds.y); - node.setAttribute('width', w); - node.setAttribute('height', h); - } - else - { - // Workaround for crisp shape-rendering in IE9 - var dd = (this.crisp && mxClient.IS_IE) ? 0.5 : 0; - node.setAttribute('x', Math.round(this.bounds.x) + dd); - node.setAttribute('y', Math.round(this.bounds.y) + dd); - - w = Math.round(w); - h = Math.round(h); - - node.setAttribute('width', w); - node.setAttribute('height', h); - } - - if (this.isRounded) - { - var f = mxConstants.RECTANGLE_ROUNDING_FACTOR * 100; - - if (this.style != null) - { - f = mxUtils.getValue(this.style, mxConstants.STYLE_ARCSIZE, f) / 100; - } - - var r = Math.min(w * f, h * f); - node.setAttribute('rx', r); - node.setAttribute('ry', r); - } - - this.updateSvgTransform(node, node == this.shadowNode); -}; - -/** - * Function: updateSvgPath - * - * Updates the path of the given node using <points>. - */ -mxShape.prototype.updateSvgPath = function(node) -{ - var d = this.createPoints('M', 'L', 'C', false); - - if (d != null) - { - node.setAttribute('d', d); - - // Smooth style for SVG (experimental) - if (this.style != null && this.style[mxConstants.STYLE_SMOOTH]) - { - var pts = this.points; - var n = pts.length; - - if (n > 3) - { - var points = 'M '+pts[0].x+' '+pts[0].y+' '; - points += ' Q '+pts[1].x + ' ' + pts[1].y + ' ' + - ' '+pts[2].x + ' ' + pts[2].y; - - for (var i = 3; i < n; i++) - { - points += ' T ' + pts[i].x + ' ' + pts[i].y; - } - - node.setAttribute('d', points); - } - } - - node.removeAttribute('x'); - node.removeAttribute('y'); - node.removeAttribute('width'); - node.removeAttribute('height'); - } -}; - -/** - * Function: updateSvgScale - * - * Updates the properties of the given node that depend on the scale and checks - * the crisp rendering attribute. - */ -mxShape.prototype.updateSvgScale = function(node) -{ - node.setAttribute('stroke-width', Math.round(Math.max(1, this.strokewidth * this.scale))); - - if (this.isDashed) - { - var phase = Math.max(1, Math.round(3 * this.scale * this.strokewidth)); - node.setAttribute('stroke-dasharray', phase + ' ' + phase); - } - - if (this.crisp && (this.roundedCrispSvg || this.isRounded != true) && - (this.rotation == null || this.rotation == 0)) - { - node.setAttribute('shape-rendering', 'crispEdges'); - } - else - { - node.removeAttribute('shape-rendering'); - } -}; - -/** - * Function: updateSvgShape - * - * Updates the bounds or points of the specified SVG node and - * updates the inner children to reflect the changes. - */ -mxShape.prototype.updateSvgShape = function(node) -{ - if (this.points != null && this.points[0] != null) - { - this.updateSvgPath(node); - } - else if (this.bounds != null) - { - this.updateSvgBounds(node); - } - - this.updateSvgScale(node); -}; - -/** - * Function: getSvgShadowTransform - * - * Returns the current transformation for SVG shadows. - */ -mxShape.prototype.getSvgShadowTransform = function(node, shadow) -{ - var dx = mxConstants.SHADOW_OFFSET_X * this.scale; - var dy = mxConstants.SHADOW_OFFSET_Y * this.scale; - - return 'translate(' + dx + ' ' + dy + ')'; -}; - -/** - * Function: updateSvgTransform - * - * Updates the tranform of the given node. - */ -mxShape.prototype.updateSvgTransform = function(node, shadow) -{ - var st = (shadow) ? this.getSvgShadowTransform() : ''; - - if (this.rotation != null && this.rotation != 0) - { - var cx = this.bounds.x + this.bounds.width / 2; - var cy = this.bounds.y + this.bounds.height / 2; - node.setAttribute('transform', 'rotate(' + this.rotation + ',' + cx + ',' + cy + ') ' + st); - } - else - { - if (shadow) - { - node.setAttribute('transform', st); - } - else - { - node.removeAttribute('transform'); - } - } -}; - -/** - * Function: reconfigure - * - * Reconfigures this shape. This will update the colors etc in - * addition to the bounds or points. - */ -mxShape.prototype.reconfigure = function() -{ - if (this.dialect == mxConstants.DIALECT_SVG) - { - if (this.innerNode != null) - { - this.configureSvgShape(this.innerNode); - } - else - { - this.configureSvgShape(this.node); - } - - if (this.insertGradientNode != null) - { - this.insertGradient(this.insertGradientNode); - this.insertGradientNode = null; - } - } - else if (mxUtils.isVml(this.node)) - { - this.node.style.visibility = 'hidden'; - this.configureVmlShape(this.node); - this.node.style.visibility = 'visible'; - } - else - { - this.node.style.visibility = 'hidden'; - this.configureHtmlShape(this.node); - this.node.style.visibility = 'visible'; - } -}; - -/** - * Function: redraw - * - * Invokes <redrawSvg>, <redrawVml> or <redrawHtml> depending on the - * dialect of the shape. - */ -mxShape.prototype.redraw = function() -{ - this.updateBoundingBox(); - - if (this.dialect == mxConstants.DIALECT_SVG) - { - this.redrawSvg(); - } - else if (mxUtils.isVml(this.node)) - { - this.node.style.visibility = 'hidden'; - this.redrawVml(); - this.node.style.visibility = 'visible'; - } - else - { - this.redrawHtml(); - } -}; - -/** - * Function: updateBoundingBox - * - * Updates the <boundingBox> for this shape using <createBoundingBox> and - * <augmentBoundingBox> and stores the result in <boundingBox>. - */ -mxShape.prototype.updateBoundingBox = function() -{ - if (this.bounds != null) - { - var bbox = this.createBoundingBox(); - this.augmentBoundingBox(bbox); - - var rot = Number(mxUtils.getValue(this.style, mxConstants.STYLE_ROTATION, 0)); - - if (rot != 0) - { - bbox = mxUtils.getBoundingBox(bbox, rot); - } - - bbox.x = Math.floor(bbox.x); - bbox.y = Math.floor(bbox.y); - // TODO: Fix rounding errors - bbox.width = Math.ceil(bbox.width); - bbox.height = Math.ceil(bbox.height); - - this.boundingBox = bbox; - } -}; - -/** - * Function: createBoundingBox - * - * Returns a new rectangle that represents the bounding box of the bare shape - * with no shadows or strokewidths. - */ -mxShape.prototype.createBoundingBox = function() -{ - return this.bounds.clone(); -}; - -/** - * Function: augmentBoundingBox - * - * Augments the bounding box with the strokewidth and shadow offsets. - */ -mxShape.prototype.augmentBoundingBox = function(bbox) -{ - if (this.isShadow) - { - bbox.width += Math.ceil(mxConstants.SHADOW_OFFSET_X * this.scale); - bbox.height += Math.ceil(mxConstants.SHADOW_OFFSET_Y * this.scale); - } - - // Adds strokeWidth - var sw = Math.ceil(this.strokewidth * this.scale); - bbox.grow(Math.ceil(sw / 2)); -}; - -/** - * Function: redrawSvg - * - * Redraws this SVG shape by invoking <updateSvgShape> on this.node, - * this.innerNode and this.shadowNode. - */ -mxShape.prototype.redrawSvg = function() -{ - if (this.innerNode != null) - { - this.updateSvgShape(this.innerNode); - - if (this.shadowNode != null) - { - this.updateSvgShape(this.shadowNode); - } - } - else - { - this.updateSvgShape(this.node); - - // Updates the transform of the shadow - if (this.shadowNode != null) - { - this.shadowNode.setAttribute('transform', this.getSvgShadowTransform()); - } - } - - this.updateSvgGlassPane(); -}; - -/** - * Function: updateVmlGlassPane - * - * Draws the glass overlay if mxConstants.STYLE_GLASS is 1. - */ -mxShape.prototype.updateVmlGlassPane = function() -{ - // Currently only used in mxLabel. Most shapes would have to be changed to use - // a group node in VML which might affect performance for glass-less cells. - if (this.bounds != null && this.node.nodeName == 'group' && this.style != null && - mxUtils.getValue(this.style, mxConstants.STYLE_GLASS, 0) == 1) - { - // Glass overlay - if (this.node.glassOverlay == null) - { - // Creates glass overlay - this.node.glassOverlay = document.createElement('v:shape'); - this.node.glassOverlay.setAttribute('filled', 'true'); - this.node.glassOverlay.setAttribute('fillcolor', 'white'); - this.node.glassOverlay.setAttribute('stroked', 'false'); - - var fillNode = document.createElement('v:fill'); - fillNode.setAttribute('type', 'gradient'); - fillNode.setAttribute('color', 'white'); - fillNode.setAttribute('color2', 'white'); - fillNode.setAttribute('opacity', '90%'); - fillNode.setAttribute('o:opacity2', '15%'); - fillNode.setAttribute('angle', '180'); - - this.node.glassOverlay.appendChild(fillNode); - this.node.appendChild(this.node.glassOverlay); - } - - var size = 0.4; - - // TODO: Mask with rectangle or rounded rectangle of label - var b = this.bounds; - var sw = Math.ceil(this.strokewidth * this.scale / 2 + 1); - var d = 'm ' + (-sw) + ' ' + (-sw) + ' l ' + (-sw) + ' ' + Math.round(b.height * size) + - ' c ' + Math.round(b.width * 0.3) + ' ' + Math.round(b.height * 0.6) + - ' ' + Math.round(b.width * 0.7) + ' ' + Math.round(b.height * 0.6) + - ' ' + Math.round(b.width + sw) + ' ' + Math.round(b.height * size) + - ' l '+Math.round(b.width + sw)+' ' + (-sw) + ' x e'; - this.node.glassOverlay.style.position = 'absolute'; - this.node.glassOverlay.style.width = b.width + 'px'; - this.node.glassOverlay.style.height = b.height + 'px'; - this.node.glassOverlay.setAttribute('coordsize', - Math.round(this.bounds.width) + ',' + - Math.round(this.bounds.height)); - this.node.glassOverlay.setAttribute('path', d); - } - else if (this.node.glassOverlay != null) - { - this.node.glassOverlay.parentNode.removeChild(this.node.glassOverlay); - this.node.glassOverlay = null; - } -}; - -/** - * Function: updateSvgGlassPane - * - * Draws the glass overlay if mxConstants.STYLE_GLASS is 1. - */ -mxShape.prototype.updateSvgGlassPane = function() -{ - if (this.node.nodeName == 'g' && this.style != null && - mxUtils.getValue(this.style, mxConstants.STYLE_GLASS, 0) == 1) - { - // Glass overlay - if (this.node.glassOverlay == null) - { - // Glass overlay gradient - if (this.node.ownerSVGElement.glassGradient == null) - { - // Creates glass overlay gradient - var glassGradient = document.createElementNS(mxConstants.NS_SVG, 'linearGradient'); - glassGradient.setAttribute('x1', '0%'); - glassGradient.setAttribute('y1', '0%'); - glassGradient.setAttribute('x2', '0%'); - glassGradient.setAttribute('y2', '100%'); - - var stop1 = document.createElementNS(mxConstants.NS_SVG, 'stop'); - stop1.setAttribute('offset', '0%'); - stop1.setAttribute('style', 'stop-color:#ffffff;stop-opacity:0.9'); - glassGradient.appendChild(stop1); - - var stop2 = document.createElementNS(mxConstants.NS_SVG, 'stop'); - stop2.setAttribute('offset', '100%'); - stop2.setAttribute('style', 'stop-color:#ffffff;stop-opacity:0.1'); - glassGradient.appendChild(stop2); - - // Finds a unique ID for the gradient - var prefix = 'mx-glass-gradient-'; - var counter = 0; - - while (document.getElementById(prefix+counter) != null) - { - counter++; - } - - glassGradient.setAttribute('id', prefix+counter); - this.node.ownerSVGElement.appendChild(glassGradient); - this.node.ownerSVGElement.glassGradient = glassGradient; - } - - // Creates glass overlay - this.node.glassOverlay = document.createElementNS(mxConstants.NS_SVG, 'path'); - // LATER: Not sure what the behaviour is for mutiple SVG elements in page. - // Probably its possible that this points to an element in another SVG - // node which when removed will result in an undefined background. - var id = this.node.ownerSVGElement.glassGradient.getAttribute('id'); - this.node.glassOverlay.setAttribute('style', 'fill:url(#'+id+');'); - this.node.appendChild(this.node.glassOverlay); - } - - var size = 0.4; - - // TODO: Mask with rectangle or rounded rectangle of label - var b = this.bounds; - var sw = Math.ceil(this.strokewidth * this.scale / 2); - var d = 'm ' + (b.x - sw) + ',' + (b.y - sw) + - ' L ' + (b.x - sw) + ',' + (b.y + b.height * size) + - ' Q '+ (b.x + b.width * 0.5) + ',' + (b.y + b.height * 0.7) + ' '+ - (b.x + b.width + sw) + ',' + (b.y + b.height * size) + - ' L ' + (b.x + b.width + sw) + ',' + (b.y - sw) + ' z'; - this.node.glassOverlay.setAttribute('d', d); - } - else if (this.node.glassOverlay != null) - { - this.node.glassOverlay.parentNode.removeChild(this.node.glassOverlay); - this.node.glassOverlay = null; - } -}; - -/** - * Function: redrawVml - * - * Redraws this VML shape by invoking <updateVmlShape> on this.node. - */ -mxShape.prototype.redrawVml = function() -{ - this.node.style.visibility = 'hidden'; - this.updateVmlShape(this.node); - this.updateVmlGlassPane(); - this.node.style.visibility = 'visible'; -}; - -/** - * Function: redrawHtml - * - * Redraws this HTML shape by invoking <updateHtmlShape> on this.node. - */ -mxShape.prototype.redrawHtml = function() -{ - this.updateHtmlShape(this.node); -}; - -/** - * Function: getRotation - * - * Returns the current rotation including direction. - */ -mxShape.prototype.getRotation = function() -{ - var rot = this.rotation || 0; - - // Default direction is east (ignored if rotation exists) - if (this.direction != null) - { - if (this.direction == 'north') - { - rot += 270; - } - else if (this.direction == 'west') - { - rot += 180; - } - else if (this.direction == 'south') - { - rot += 90; - } - } - - return rot; -}; - -/** - * Function: createPath - * - * Creates an <mxPath> for the specified format and origin. The path object is - * then passed to <redrawPath> and <mxPath.getPath> is returned. - */ -mxShape.prototype.createPath = function(arg) -{ - var x = this.bounds.x; - var y = this.bounds.y; - var w = this.bounds.width; - var h = this.bounds.height; - var dx = 0; - var dy = 0; - - // Inverts bounds for stencils which are rotated 90 or 270 degrees - if (this.direction == 'north' || this.direction == 'south') - { - dx = (w - h) / 2; - dy = (h - w) / 2; - x += dx; - y += dy; - var tmp = w; - w = h; - h = tmp; - } - - var rotation = this.getRotation(); - var path = null; - - if (this.dialect == mxConstants.DIALECT_SVG) - { - path = new mxPath('svg'); - path.setTranslate(x, y); - - // Adds rotation as a separate transform - if (rotation != 0) - { - var cx = this.bounds.getCenterX(); - var cy = this.bounds.getCenterY(); - var transform = 'rotate(' + rotation + ' ' + cx + ' ' + cy + ')'; - - if (this.innerNode != null) - { - this.innerNode.setAttribute('transform', transform); - } - - if (this.foreground != null) - { - this.foreground.setAttribute('transform', transform); - } - - // Shadow needs different transform so that it ends up on the correct side - if (this.shadowNode != null) - { - this.shadowNode.setAttribute('transform', this.getSvgShadowTransform() + ' ' + transform); - } - } - } - else - { - path = new mxPath('vml'); - path.setTranslate(dx, -dx); - path.scale = this.vmlScale; - - if (rotation != 0) - { - this.node.style.rotation = rotation; - } - } - - this.redrawPath(path, x, y, w, h, arg); - - return path.getPath(); -}; - -/** - * Function: redrawPath - * - * Draws the path for this shape. This implementation is empty. See - * <mxActor> and <mxCylinder> for implementations. - */ -mxShape.prototype.redrawPath = function(path, x, y, w, h) -{ - // do nothing -}; diff --git a/src/js/shape/mxStencil.js b/src/js/shape/mxStencil.js deleted file mode 100644 index d0e1a63..0000000 --- a/src/js/shape/mxStencil.js +++ /dev/null @@ -1,1585 +0,0 @@ -/** - * $Id: mxStencil.js,v 1.91 2012-07-16 10:22:44 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxStencil - * - * Implements a generic shape which is based on a XML node as a description. - * The node contains a background and a foreground node, which contain the - * definition to render the respective part of the shape. Note that the - * fill, stroke or fillstroke of the background is be the first statement - * of the foreground. This is because the content of the background node - * maybe used to not only render the shape itself, but also its shadow and - * other elements which do not require a fill, stroke or fillstroke. - * - * The shape uses a coordinate system with a width of 100 and a height of - * 100 by default. This can be changed by setting the w and h attribute of - * the shape element. The aspect attribute can be set to "variable" (default) - * or "fixed". If fixed is used, then the aspect which is defined via the w - * and h attribute is kept constant while the shape is scaled. - * - * The possible contents of the background and foreground elements are rect, - * ellipse, roundrect, text, image, include-shape or paths. A path element - * contains move, line, curve, quad, arc and close elements. The rect, ellipse - * and roundrect elements may be thought of as special path elements. All these - * path elements must be followed by either fill, stroke or fillstroke (note - * that text, image and include-shape or not path elements). - * - * The background element can be empty or contain at most one path element. It - * should not contain a text, image or include-shape element. If the background - * element is empty, then no shadow or glass effect will be rendered. If the - * background element is non-empty, then the corresponding fill, stroke or - * fillstroke should be the first element in the subsequent foreground element. - * - * The format of the XML is "a simplified HTML 5 Canvas". Each command changes - * the "current" state, so eg. a linecap, linejoin will be used for all - * subsequent line drawing, unless a save/restore appears, which saves/restores - * a state in a stack. - * - * The connections section contains the fixed connection points for a stencil. - * The perimeter attribute of the constraint element should have a value of 0 - * or 1 (default), where 1 (true) specifies that the given point should be - * projected into the perimeter of the given shape. - * - * The x- and y-coordinates are typically between 0 and 1 and define the - * location of the connection point relative to the width and height of the - * shape. - * - * The dashpattern directive sets the current dashpattern. The format for the - * pattern attribute is a space-separated sequence of numbers, eg. 5 5 5 5, - * that specifies the lengths of alternating dashes and spaces in dashed lines. - * The dashpattern should be used together with the dashed directive to - * enabled/disable the dashpattern. The default dashpattern is 3 3. - * - * The strokewidth attribute defines a fixed strokewidth for the shape. It - * can contain a numeric value or the keyword "inherit", which means that the - * strokeWidth from the cell's style will be used and muliplied with the shape's - * scale. If numeric values are used, those are multiplied with the minimum - * scale used to render the stencil inside the shape's bounds. - * - * Constructor: mxStencilShape - * - * Constructs a new generic shape by setting <desc> to the given XML node and - * invoking <parseDescription> and <parseConstraints>. - * - * Parameters: - * - * desc - XML node that contains the stencil description. - */ -function mxStencil(desc) -{ - this.desc = desc; - this.parseDescription(); - this.parseConstraints(); -}; - -/** - * Variable: desc - * - * Holds the XML node with the stencil description. - */ -mxStencil.prototype.desc = null; - -/** - * Variable: constraints - * - * Holds an array of <mxConnectionConstraints> as defined in the shape. - */ -mxStencil.prototype.constraints = null; - -/** - * Variable: aspect - * - * Holds the aspect of the shape. Default is 'auto'. - */ -mxStencil.prototype.aspect = null; - -/** - * Variable: w0 - * - * Holds the width of the shape. Default is 100. - */ -mxStencil.prototype.w0 = null; - -/** - * Variable: h0 - * - * Holds the height of the shape. Default is 100. - */ -mxStencil.prototype.h0 = null; - -/** - * Variable: bgNodes - * - * Holds the XML node with the stencil description. - */ -mxStencil.prototype.bgNode = null; - -/** - * Variable: fgNodes - * - * Holds the XML node with the stencil description. - */ -mxStencil.prototype.fgNode = null; - -/** - * Variable: strokewidth - * - * Holds the strokewidth direction from the description. - */ -mxStencil.prototype.strokewidth = null; - -/** - * Function: parseDescription - * - * Reads <w0>, <h0>, <aspect>, <bgNodes> and <fgNodes> from <desc>. - */ -mxStencil.prototype.parseDescription = function() -{ - // LATER: Preprocess nodes for faster painting - this.fgNode = this.desc.getElementsByTagName('foreground')[0]; - this.bgNode = this.desc.getElementsByTagName('background')[0]; - this.w0 = Number(this.desc.getAttribute('w') || 100); - this.h0 = Number(this.desc.getAttribute('h') || 100); - - // Possible values for aspect are: variable and fixed where - // variable means fill the available space and fixed means - // use w0 and h0 to compute the aspect. - var aspect = this.desc.getAttribute('aspect'); - this.aspect = (aspect != null) ? aspect : 'variable'; - - // Possible values for strokewidth are all numbers and "inherit" - // where the inherit means take the value from the style (ie. the - // user-defined stroke-width). Note that the strokewidth is scaled - // by the minimum scaling that is used to draw the shape (sx, sy). - var sw = this.desc.getAttribute('strokewidth'); - this.strokewidth = (sw != null) ? sw : '1'; -}; - -/** - * Function: parseConstraints - * - * Reads the constraints from <desc> into <constraints> using - * <parseConstraint>. - */ -mxStencil.prototype.parseConstraints = function() -{ - var conns = this.desc.getElementsByTagName('connections')[0]; - - if (conns != null) - { - var tmp = mxUtils.getChildNodes(conns); - - if (tmp != null && tmp.length > 0) - { - this.constraints = []; - - for (var i = 0; i < tmp.length; i++) - { - this.constraints.push(this.parseConstraint(tmp[i])); - } - } - } -}; - -/** - * Function: parseConstraint - * - * Parses the given XML node and returns its <mxConnectionConstraint>. - */ -mxStencil.prototype.parseConstraint = function(node) -{ - var x = Number(node.getAttribute('x')); - var y = Number(node.getAttribute('y')); - var perimeter = node.getAttribute('perimeter') == '1'; - - return new mxConnectionConstraint(new mxPoint(x, y), perimeter); -}; - -/** - * Function: evaluateAttribute - * - * Gets the attribute for the given name from the given node. If the attribute - * does not exist then the text content of the node is evaluated and if it is - * a function it is invoked with <state> as the only argument and the return - * value is used as the attribute value to be returned. - */ -mxStencil.prototype.evaluateAttribute = function(node, attribute, state) -{ - var result = node.getAttribute(attribute); - - if (result == null) - { - var text = mxUtils.getTextContent(node); - - if (text != null) - { - var funct = mxUtils.eval(text); - - if (typeof(funct) == 'function') - { - result = funct(state); - } - } - } - - return result; -}; - -/** - * Function: renderDom - * - * Updates the SVG or VML shape. - */ -mxStencil.prototype.renderDom = function(shape, bounds, parentNode, state) -{ - var vml = shape.dialect != mxConstants.DIALECT_SVG; - var vmlScale = (document.documentMode == 8) ? 1 : shape.vmlScale; - var rotation = shape.rotation || 0; - var inverse = false; - - // New styles for shape flipping the stencil - var flipH = shape.style[mxConstants.STYLE_STENCIL_FLIPH]; - var flipV = shape.style[mxConstants.STYLE_STENCIL_FLIPV]; - - if (flipH ? !flipV : flipV) - { - rotation *= -1; - } - - // Default direction is east (ignored if rotation exists) - if (shape.direction != null) - { - if (shape.direction == 'north') - { - rotation += 270; - } - else if (shape.direction == 'west') - { - rotation += 180; - } - else if (shape.direction == 'south') - { - rotation += 90; - } - - inverse = (shape.direction == 'north' || shape.direction == 'south'); - } - - if (flipH && flipV) - { - rotation += 180; - flipH = false; - flipV = false; - } - - // SVG transform should be applied on all child shapes - var svgTransform = ''; - - // Implements direction style and vertical/horizontal flip - // via container transformation. - if (vml) - { - if (flipH) - { - parentNode.style.flip = 'x'; - } - else if (flipV) - { - parentNode.style.flip = 'y'; - } - - if (rotation != 0) - { - parentNode.style.rotation = rotation; - } - } - else - { - if (flipH || flipV) - { - var sx = 1; - var sy = 1; - var dx = 0; - var dy = 0; - - if (flipH) - { - sx = -1; - dx = -bounds.width - 2 * bounds.x; - } - - if (flipV) - { - sy = -1; - dy = -bounds.height - 2 * bounds.y; - } - - svgTransform = 'scale(' + sx + ' ' + sy + ') translate(' + dx + ' ' + dy + ')'; - } - - // Adds rotation as a separate transform - if (rotation != 0) - { - var cx = bounds.getCenterX(); - var cy = bounds.getCenterY(); - svgTransform += ' rotate(' + rotation + ' ' + cx + ' ' + cy + ')'; - } - } - - var background = (state == null); - - if (this.bgNode != null || this.fgNode != null) - { - var x0 = (vml && state == null) ? 0 : bounds.x; - var y0 = (vml && state == null) ? 0 : bounds.y; - var sx = bounds.width / this.w0; - var sy = bounds.height / this.h0; - - // Stores current location inside path - this.lastMoveX = 0; - this.lastMoveY = 0; - - if (inverse) - { - sy = bounds.width / this.h0; - sx = bounds.height / this.w0; - - var delta = (bounds.width - bounds.height) / 2; - - x0 += delta; - y0 -= delta; - } - - if (this.aspect == 'fixed') - { - sy = Math.min(sx, sy); - sx = sy; - - // Centers the shape inside the available space - if (inverse) - { - x0 += (bounds.height - this.w0 * sx) / 2; - y0 += (bounds.width - this.h0 * sy) / 2; - } - else - { - x0 += (bounds.width - this.w0 * sx) / 2; - y0 += (bounds.height - this.h0 * sy) / 2; - } - } - - // Workaround to improve VML rendering precision. - if (vml) - { - sx *= vmlScale; - sy *= vmlScale; - x0 *= vmlScale; - y0 *= vmlScale; - } - - var minScale = Math.min(sx, sy); - - // Stack of states for save/restore ops - var stack = []; - - var currentState = (state != null) ? state : - { - fillColorAssigned: false, - fill: shape.fill, - stroke: shape.stroke, - strokeWidth: (this.strokewidth == 'inherit') ? - Number(shape.strokewidth) * shape.scale : - Number(this.strokewidth) * minScale / ((vml) ? vmlScale : 1), - dashed: shape.isDashed, - dashpattern: [3, 3], - alpha: shape.opacity, - linejoin: 'miter', - fontColor: '#000000', - fontSize: mxConstants.DEFAULT_FONTSIZE, - fontFamily: mxConstants.DEFAULT_FONTFAMILY, - fontStyle: 0 - }; - - var currentPath = null; - var currentPoints = null; - - var configurePath = function(path, state) - { - var sw = Math.max(1, state.strokeWidth); - - if (vml) - { - path.strokeweight = Math.round(sw) + 'px'; - - if (state.fill != null) - { - // Gradient in foregrounds not supported because special gradients - // with bounds must be created for each element in graphics-canvases - var gradient = (!state.fillColorAssigned) ? shape.gradient : null; - var fill = document.createElement('v:fill'); - shape.updateVmlFill(fill, state.fill, gradient, shape.gradientDirection, state.alpha); - path.appendChild(fill); - } - else - { - path.filled = 'false'; - } - - if (state.stroke != null) - { - path.stroked = 'true'; - path.strokecolor = state.stroke; - } - else - { - path.stroked = 'false'; - } - - path.style.position = 'absolute'; - } - else - { - path.setAttribute('stroke-width', sw); - - if (state.fill != null && state.fillColorAssigned) - { - path.setAttribute('fill', state.fill); - } - - if (state.stroke != null) - { - path.setAttribute('stroke', state.stroke); - } - } - }; - - var addToPath = function(s) - { - if (currentPath != null && currentPoints != null) - { - currentPoints.push(s); - } - }; - - var round = function(value) - { - return (vml) ? Math.round(value) : value; - }; - - // Will be moved to a hook later for example to set text values - var renderNode = function(node) - { - var name = node.nodeName; - - var fillOp = name == 'fill'; - var strokeOp = name == 'stroke'; - var fillStrokeOp = name == 'fillstroke'; - - if (name == 'save') - { - stack.push(currentState); - currentState = mxUtils.clone(currentState); - } - else if (name == 'restore') - { - currentState = stack.pop(); - } - else if (name == 'path') - { - currentPoints = []; - - if (vml) - { - currentPath = document.createElement('v:shape'); - configurePath.call(this, currentPath, currentState); - var w = Math.round(bounds.width) * vmlScale; - var h = Math.round(bounds.height) * vmlScale; - currentPath.style.width = w + 'px'; - currentPath.style.height = h + 'px'; - currentPath.coordsize = w + ',' + h; - } - else - { - currentPath = document.createElementNS(mxConstants.NS_SVG, 'path'); - configurePath.call(this, currentPath, currentState); - - if (svgTransform.length > 0) - { - currentPath.setAttribute('transform', svgTransform); - } - - if (node.getAttribute('crisp') == '1') - { - currentPath.setAttribute('shape-rendering', 'crispEdges'); - } - } - - // Renders the elements inside the given path - var childNode = node.firstChild; - - while (childNode != null) - { - if (childNode.nodeType == mxConstants.NODETYPE_ELEMENT) - { - renderNode.call(this, childNode); - } - - childNode = childNode.nextSibling; - } - - // Ends the current path - if (vml) - { - addToPath('e'); - currentPath.path = currentPoints.join(''); - } - else - { - currentPath.setAttribute('d', currentPoints.join('')); - } - } - else if (name == 'move') - { - var op = (vml) ? 'm' : 'M'; - this.lastMoveX = round(x0 + Number(node.getAttribute('x')) * sx); - this.lastMoveY = round(y0 + Number(node.getAttribute('y')) * sy); - addToPath(op + ' ' + this.lastMoveX + ' ' + this.lastMoveY); - } - else if (name == 'line') - { - var op = (vml) ? 'l' : 'L'; - this.lastMoveX = round(x0 + Number(node.getAttribute('x')) * sx); - this.lastMoveY = round(y0 + Number(node.getAttribute('y')) * sy); - addToPath(op + ' ' + this.lastMoveX + ' ' + this.lastMoveY); - } - else if (name == 'quad') - { - if (vml) - { - var cpx0 = this.lastMoveX; - var cpy0 = this.lastMoveY; - var qpx1 = x0 + Number(node.getAttribute('x1')) * sx; - var qpy1 = y0 + Number(node.getAttribute('y1')) * sy; - var cpx3 = x0 + Number(node.getAttribute('x2')) * sx; - var cpy3 = y0 + Number(node.getAttribute('y2')) * sy; - - var cpx1 = cpx0 + 2/3 * (qpx1 - cpx0); - var cpy1 = cpy0 + 2/3 * (qpy1 - cpy0); - - var cpx2 = cpx3 + 2/3 * (qpx1 - cpx3); - var cpy2 = cpy3 + 2/3 * (qpy1 - cpy3); - - addToPath('c ' + Math.round(cpx1) + ' ' + Math.round(cpy1) + ' ' + - Math.round(cpx2) + ' ' + Math.round(cpy2) + ' ' + - Math.round(cpx3) + ' ' + Math.round(cpy3)); - - this.lastMoveX = cpx3; - this.lastMoveY = cpy3; - } - else - { - this.lastMoveX = x0 + Number(node.getAttribute('x2')) * sx; - this.lastMoveY = y0 + Number(node.getAttribute('y2')) * sy; - - addToPath('Q ' + (x0 + Number(node.getAttribute('x1')) * sx) + ' ' + - (y0 + Number(node.getAttribute('y1')) * sy) + ' ' + - this.lastMoveX + ' ' + this.lastMoveY); - } - } - else if (name == 'curve') - { - var op = (vml) ? 'c' : 'C'; - this.lastMoveX = round(x0 + Number(node.getAttribute('x3')) * sx); - this.lastMoveY = round(y0 + Number(node.getAttribute('y3')) * sy); - - addToPath(op + ' ' + round(x0 + Number(node.getAttribute('x1')) * sx) + ' ' + - round(y0 + Number(node.getAttribute('y1')) * sy) + ' ' + - round(x0 + Number(node.getAttribute('x2')) * sx) + ' ' + - round(y0 + Number(node.getAttribute('y2')) * sy) + ' ' + - this.lastMoveX + ' ' + this.lastMoveY); - } - else if (name == 'close') - { - addToPath((vml) ? 'x' : 'Z'); - } - else if (name == 'rect' || name == 'roundrect') - { - var rounded = name == 'roundrect'; - var x = round(x0 + Number(node.getAttribute('x')) * sx); - var y = round(y0 + Number(node.getAttribute('y')) * sy); - var w = round(Number(node.getAttribute('w')) * sx); - var h = round(Number(node.getAttribute('h')) * sy); - - var arcsize = node.getAttribute('arcsize'); - - if (arcsize == 0) - { - arcsize = mxConstants.RECTANGLE_ROUNDING_FACTOR * 100; - } - - if (vml) - { - // LATER: Use HTML for non-rounded, gradientless rectangles - currentPath = document.createElement((rounded) ? 'v:roundrect' : 'v:rect'); - currentPath.style.left = x + 'px'; - currentPath.style.top = y + 'px'; - currentPath.style.width = w + 'px'; - currentPath.style.height = h + 'px'; - - if (rounded) - { - currentPath.setAttribute('arcsize', String(arcsize) + '%'); - } - } - else - { - currentPath = document.createElementNS(mxConstants.NS_SVG, 'rect'); - currentPath.setAttribute('x', x); - currentPath.setAttribute('y', y); - currentPath.setAttribute('width', w); - currentPath.setAttribute('height', h); - - if (rounded) - { - var factor = Number(arcsize) / 100; - var r = Math.min(w * factor, h * factor); - currentPath.setAttribute('rx', r); - currentPath.setAttribute('ry', r); - } - - if (svgTransform.length > 0) - { - currentPath.setAttribute('transform', svgTransform); - } - - if (node.getAttribute('crisp') == '1') - { - currentPath.setAttribute('shape-rendering', 'crispEdges'); - } - } - - configurePath.call(this, currentPath, currentState); - } - else if (name == 'ellipse') - { - var x = round(x0 + Number(node.getAttribute('x')) * sx); - var y = round(y0 + Number(node.getAttribute('y')) * sy); - var w = round(Number(node.getAttribute('w')) * sx); - var h = round(Number(node.getAttribute('h')) * sy); - - if (vml) - { - currentPath = document.createElement('v:arc'); - currentPath.startangle = '0'; - currentPath.endangle = '360'; - currentPath.style.left = x + 'px'; - currentPath.style.top = y + 'px'; - currentPath.style.width = w + 'px'; - currentPath.style.height = h + 'px'; - } - else - { - currentPath = document.createElementNS(mxConstants.NS_SVG, 'ellipse'); - currentPath.setAttribute('cx', x + w / 2); - currentPath.setAttribute('cy', y + h / 2); - currentPath.setAttribute('rx', w / 2); - currentPath.setAttribute('ry', h / 2); - - if (svgTransform.length > 0) - { - currentPath.setAttribute('transform', svgTransform); - } - } - - configurePath.call(this, currentPath, currentState); - } - else if (name == 'arc') - { - var r1 = Number(node.getAttribute('rx')) * sx; - var r2 = Number(node.getAttribute('ry')) * sy; - var angle = Number(node.getAttribute('x-axis-rotation')); - var largeArcFlag = Number(node.getAttribute('large-arc-flag')); - var sweepFlag = Number(node.getAttribute('sweep-flag')); - var x = x0 + Number(node.getAttribute('x')) * sx; - var y = y0 + Number(node.getAttribute('y')) * sy; - - if (vml) - { - var curves = mxUtils.arcToCurves(this.lastMoveX, this.lastMoveY, r1, r2, angle, largeArcFlag, sweepFlag, x, y); - - for (var i = 0; i < curves.length; i += 6) - { - addToPath('c' + ' ' + Math.round(curves[i]) + ' ' + Math.round(curves[i + 1]) + ' ' + - Math.round(curves[i + 2]) + ' ' + Math.round(curves[i + 3]) + ' ' + - Math.round(curves[i + 4]) + ' ' + Math.round(curves[i + 5])); - - this.lastMoveX = curves[i + 4]; - this.lastMoveY = curves[i + 5]; - } - } - else - { - addToPath('A ' + r1 + ',' + r2 + ' ' + angle + ' ' + largeArcFlag + ',' + sweepFlag + ' ' + x + ',' + y); - this.lastMoveX = x0 + x; - this.lastMoveY = y0 + y; - } - } - else if (name == 'image') - { - var src = this.evaluateAttribute(node, 'src', shape.state); - - if (src != null) - { - var x = round(x0 + Number(node.getAttribute('x')) * sx); - var y = round(y0 + Number(node.getAttribute('y')) * sy); - var w = round(Number(node.getAttribute('w')) * sx); - var h = round(Number(node.getAttribute('h')) * sy); - - // TODO: _Not_ providing an aspect in the shapes format has the advantage - // of not needing a callback to adjust the image in VML. Since the shape - // developer can specify the aspect via width and height this should OK. - //var aspect = node.getAttribute('aspect') != '0'; - var aspect = false; - var flipH = node.getAttribute('flipH') == '1'; - var flipV = node.getAttribute('flipV') == '1'; - - if (vml) - { - currentPath = document.createElement('v:image'); - currentPath.style.filter = 'alpha(opacity=' + currentState.alpha + ')'; - currentPath.style.left = x + 'px'; - currentPath.style.top = y + 'px'; - currentPath.style.width = w + 'px'; - currentPath.style.height = h + 'px'; - currentPath.src = src; - - if (flipH && flipV) - { - currentPath.style.rotation = '180'; - } - else if (flipH) - { - currentPath.style.flip = 'x'; - } - else if (flipV) - { - currentPath.style.flip = 'y'; - } - } - else - { - currentPath = document.createElementNS(mxConstants.NS_SVG, 'image'); - currentPath.setAttributeNS(mxConstants.NS_XLINK, 'xlink:href', src); - currentPath.setAttribute('opacity', currentState.alpha / 100); - currentPath.setAttribute('x', x); - currentPath.setAttribute('y', y); - currentPath.setAttribute('width', w); - currentPath.setAttribute('height', h); - - if (!aspect) - { - currentPath.setAttribute('preserveAspectRatio', 'none'); - } - - if (flipH || flipV) - { - var scx = 1; - var scy = 1; - var dx = 0; - var dy = 0; - - if (flipH) - { - scx = -1; - dx = -w - 2 * x; - } - - if (flipV) - { - scy = -1; - dy = -h - 2 * y; - } - - currentPath.setAttribute('transform', svgTransform + 'scale(' + scx + ' ' + scy + ')' + - ' translate('+dx+' '+dy+') '); - } - else - { - currentPath.setAttribute('transform', svgTransform); - } - } - - parentNode.appendChild(currentPath); - } - } - else if (name == 'include-shape') - { - var stencil = mxStencilRegistry.getStencil(node.getAttribute('name')); - - if (stencil != null) - { - var x = x0 + Number(node.getAttribute('x')) * sx; - var y = y0 + Number(node.getAttribute('y')) * sy; - var w = Number(node.getAttribute('w')) * sx; - var h = Number(node.getAttribute('h')) * sy; - - stencil.renderDom(shape, new mxRectangle(x, y, w, h), parentNode, currentState); - } - } - // Additional labels are currently disabled. Needs fixing of VML - // text positon, SVG text rotation and ignored baseline in FF - else if (name == 'text') - { - var str = this.evaluateAttribute(node, 'str', shape.state); - - if (str != null) - { - var x = round(x0 + Number(node.getAttribute('x')) * sx); - var y = round(y0 + Number(node.getAttribute('y')) * sy); - var align = node.getAttribute('align') || 'left'; - var valign = node.getAttribute('valign') || 'top'; - - if (vml) - { - // Renders a single line of text with full rotation support - currentPath = document.createElement('v:shape'); - currentPath.style.position = 'absolute'; - currentPath.style.width = '1px'; - currentPath.style.height = '1px'; - currentPath.style.left = x + 'px'; - currentPath.style.top = y + 'px'; - - var fill = document.createElement('v:fill'); - fill.color = currentState.fontColor; - fill.on = 'true'; - currentPath.appendChild(fill); - - var stroke = document.createElement('v:stroke'); - stroke.on = 'false'; - currentPath.appendChild(stroke); - - var path = document.createElement('v:path'); - path.textpathok = 'true'; - path.v = 'm ' + x + ' ' + y + ' l ' + (x + 1) + ' ' + y; - - currentPath.appendChild(path); - - var tp = document.createElement('v:textpath'); - tp.style.cssText = 'v-text-align:' + align; - tp.style.fontSize = Math.round(currentState.fontSize / vmlScale) + 'px'; - - // FIXME: Font-family seems to be ignored for textpath - tp.style.fontFamily = currentState.fontFamily; - tp.string = str; - tp.on = 'true'; - - // Bold - if ((currentState.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD) - { - tp.style.fontWeight = 'bold'; - } - - // Italic - if ((currentState.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC) - { - tp.style.fontStyle = 'italic'; - } - - // FIXME: Text decoration not supported in textpath - if ((currentState.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE) - { - tp.style.textDecoration = 'underline'; - } - - // LATER: Find vertical center for div via CSS if possible - if (valign == 'top') - { - currentPath.style.top = (y + currentState.fontSize / 2) + 'px'; - } - else if (valign == 'bottom') - { - currentPath.style.top = (y - currentState.fontSize / 3) + 'px'; - } - - currentPath.appendChild(tp); - } - else - { - currentPath = document.createElementNS(mxConstants.NS_SVG, 'text'); - currentPath.setAttribute('fill', currentState.fontColor); - currentPath.setAttribute('font-family', currentState.fontFamily); - currentPath.setAttribute('font-size', currentState.fontSize); - currentPath.setAttribute('stroke', 'none'); - currentPath.setAttribute('x', x); - currentPath.appendChild(document.createTextNode(str)); - - // Bold - if ((currentState.fontStyle & mxConstants.FONT_BOLD) == mxConstants.FONT_BOLD) - { - currentPath.setAttribute('font-weight', 'bold'); - } - - // Italic - if ((currentState.fontStyle & mxConstants.FONT_ITALIC) == mxConstants.FONT_ITALIC) - { - currentPath.setAttribute('font-style', 'italic'); - } - - // Underline - if ((currentState.fontStyle & mxConstants.FONT_UNDERLINE) == mxConstants.FONT_UNDERLINE) - { - currentPath.setAttribute('text-decoration', uline); - } - - // Horizontal alignment - if (align == 'left') - { - align = 'start'; - } - else if (align == 'center') - { - align = 'middle'; - } - else if (align == 'right') - { - align = 'end'; - } - - currentPath.setAttribute('text-anchor', align); - - // Vertical alignment - // Uses dy because FF ignores alignment-baseline - if (valign == 'top') - { - currentPath.setAttribute('y', y + currentState.fontSize / 5); - currentPath.setAttribute('dy', '1ex'); - } - else if (valign == 'middle') - { - currentPath.setAttribute('y', y + currentState.fontSize / 8); - currentPath.setAttribute('dy', '0.5ex'); - } - else - { - currentPath.setAttribute('y', y); - } - - if (svgTransform.length > 0) - { - currentPath.setAttribute('transform', svgTransform); - } - } - - parentNode.appendChild(currentPath); - } - } - else if (fillOp || strokeOp || fillStrokeOp) - { - if (currentPath != null) - { - var pattern = null; - - if (currentState.dashed) - { - var f = (vml) ? minScale : Number(currentPath.getAttribute('stroke-width')); - var pat = []; - - for (var i = 0; i < currentState.dashpattern.length; i++) - { - pat.push(Math.max(1, Math.round(Number(currentState.dashpattern[i]) * f))); - } - - pattern = pat.join(' '); - } - - if (strokeOp || fillStrokeOp) - { - if (vml) - { - var stroke = document.createElement('v:stroke'); - stroke.endcap = currentState.linecap || 'flat'; - stroke.joinstyle = currentState.linejoin || 'miter'; - stroke.miterlimit = currentState.miterlimit || '10'; - currentPath.appendChild(stroke); - - // TODO: Dashpattern support in VML is limited, we should - // map this to VML or allow for a separate VML dashstyle. - if (pattern != null) - { - stroke.dashstyle = pattern; - } - } - else - { - if (currentState.linejoin != null) - { - currentPath.setAttribute('stroke-linejoin', currentState.linejoin); - } - - if (currentState.linecap != null) - { - // flat is called butt in SVG - var value = currentState.linecap; - - if (value == 'flat') - { - value = 'butt'; - } - - currentPath.setAttribute('stroke-linecap', value); - } - - if (currentState.miterlimit != null) - { - currentPath.setAttribute('stroke-miterlimit', currentState.miterlimit); - } - - // Handles dash pattern - if (pattern != null) - { - currentPath.setAttribute('stroke-dasharray', pattern); - } - } - } - - // Adds the shadow - if (background && shape.isShadow) - { - var dx = mxConstants.SHADOW_OFFSET_X * shape.scale; - var dy = mxConstants.SHADOW_OFFSET_Y * shape.scale; - - // Adds the shadow - if (vml) - { - var shadow = document.createElement('v:shadow'); - shadow.setAttribute('on', 'true'); - shadow.setAttribute('color', mxConstants.SHADOWCOLOR); - shadow.setAttribute('offset', Math.round(dx) + 'px,' + Math.round(dy) + 'px'); - shadow.setAttribute('opacity', (mxConstants.SHADOW_OPACITY * 100) + '%'); - - var stroke = document.createElement('v:stroke'); - stroke.endcap = currentState.linecap || 'flat'; - stroke.joinstyle = currentState.linejoin || 'miter'; - stroke.miterlimit = currentState.miterlimit || '10'; - - if (pattern != null) - { - stroke.dashstyle = pattern; - } - - shadow.appendChild(stroke); - currentPath.appendChild(shadow); - } - else - { - var shadow = currentPath.cloneNode(true); - shadow.setAttribute('stroke', mxConstants.SHADOWCOLOR); - - if (currentState.fill != null && (fillOp || fillStrokeOp)) - { - shadow.setAttribute('fill', mxConstants.SHADOWCOLOR); - } - else - { - shadow.setAttribute('fill', 'none'); - } - - shadow.setAttribute('transform', 'translate(' + dx + ' ' + dy + ') ' + - (shadow.getAttribute('transform') || '')); - shadow.setAttribute('opacity', mxConstants.SHADOW_OPACITY); - parentNode.appendChild(shadow); - } - } - - if (fillOp) - { - if (vml) - { - currentPath.stroked = 'false'; - } - else - { - currentPath.setAttribute('stroke', 'none'); - } - } - else if (strokeOp) - { - if (vml) - { - currentPath.filled = 'false'; - } - else - { - currentPath.setAttribute('fill', 'none'); - } - } - - parentNode.appendChild(currentPath); - } - - // Background was painted - if (background) - { - background = false; - } - } - else if (name == 'linecap') - { - currentState.linecap = node.getAttribute('cap'); - } - else if (name == 'linejoin') - { - currentState.linejoin = node.getAttribute('join'); - } - else if (name == 'miterlimit') - { - currentState.miterlimit = node.getAttribute('limit'); - } - else if (name == 'dashed') - { - currentState.dashed = node.getAttribute('dashed') == '1'; - } - else if (name == 'dashpattern') - { - var value = node.getAttribute('pattern'); - - if (value != null && value.length > 0) - { - currentState.dashpattern = value.split(' '); - } - } - else if (name == 'strokewidth') - { - currentState.strokeWidth = node.getAttribute('width') * minScale; - - if (vml) - { - currentState.strokeWidth /= vmlScale; - } - } - else if (name == 'strokecolor') - { - currentState.stroke = node.getAttribute('color'); - } - else if (name == 'fillcolor') - { - currentState.fill = node.getAttribute('color'); - currentState.fillColorAssigned = true; - } - else if (name == 'alpha') - { - currentState.alpha = Number(node.getAttribute('alpha')); - } - else if (name == 'fontcolor') - { - currentState.fontColor = node.getAttribute('color'); - } - else if (name == 'fontsize') - { - currentState.fontSize = Number(node.getAttribute('size')) * minScale; - } - else if (name == 'fontfamily') - { - currentState.fontFamily = node.getAttribute('family'); - } - else if (name == 'fontstyle') - { - currentState.fontStyle = Number(node.getAttribute('style')); - } - }; - - // Adds a transparent rectangle in the background for hit-detection in SVG - if (!vml) - { - var rect = document.createElementNS(mxConstants.NS_SVG, 'rect'); - rect.setAttribute('x', bounds.x); - rect.setAttribute('y', bounds.y); - rect.setAttribute('width', bounds.width); - rect.setAttribute('height', bounds.height); - rect.setAttribute('fill', 'none'); - rect.setAttribute('stroke', 'none'); - parentNode.appendChild(rect); - } - - // Background switches to false after fill/stroke of the background - if (this.bgNode != null) - { - var tmp = this.bgNode.firstChild; - - while (tmp != null) - { - if (tmp.nodeType == mxConstants.NODETYPE_ELEMENT) - { - renderNode.call(this, tmp); - } - - tmp = tmp.nextSibling; - } - } - else - { - background = false; - } - - if (this.fgNode != null) - { - var tmp = this.fgNode.firstChild; - - while (tmp != null) - { - if (tmp.nodeType == mxConstants.NODETYPE_ELEMENT) - { - renderNode.call(this, tmp); - } - - tmp = tmp.nextSibling; - } - } - } -}; - -/** - * Function: drawShape - * - * Draws this stencil inside the given bounds. - */ -mxStencil.prototype.drawShape = function(canvas, state, bounds, background) -{ - // TODO: Unify with renderDom, check performance of pluggable shape, - // internal structure (array of special structs?), relative and absolute - // coordinates (eg. note shape, process vs star, actor etc.), text rendering - // and non-proportional scaling, how to implement pluggable edge shapes - // (start, segment, end blocks), pluggable markers, how to implement - // swimlanes (title area) with this API, add icon, horizontal/vertical - // label, indicator for all shapes, rotation - var node = (background) ? this.bgNode : this.fgNode; - - if (node != null) - { - var direction = mxUtils.getValue(state.style, mxConstants.STYLE_DIRECTION, null); - var aspect = this.computeAspect(state, bounds, direction); - var minScale = Math.min(aspect.width, aspect.height); - var sw = (this.strokewidth == 'inherit') ? - Number(mxUtils.getNumber(state.style, mxConstants.STYLE_STROKEWIDTH, 1)) * state.view.scale : - Number(this.strokewidth) * minScale; - this.lastMoveX = 0; - this.lastMoveY = 0; - canvas.setStrokeWidth(sw); - - var tmp = node.firstChild; - - while (tmp != null) - { - if (tmp.nodeType == mxConstants.NODETYPE_ELEMENT) - { - this.drawNode(canvas, state, tmp, aspect); - } - - tmp = tmp.nextSibling; - } - - return true; - } - - return false; -}; - -/** - * Function: computeAspect - * - * Returns a rectangle that contains the offset in x and y and the horizontal - * and vertical scale in width and height used to draw this shape inside the - * given <mxRectangle>. - * - * Parameters: - * - * state - <mxCellState> for which the shape should be drawn. - * bounds - <mxRectangle> that should contain the stencil. - * direction - Optional direction of the shape to be darwn. - */ -mxStencil.prototype.computeAspect = function(state, bounds, direction) -{ - var x0 = bounds.x; - var y0 = bounds.y; - var sx = bounds.width / this.w0; - var sy = bounds.height / this.h0; - - var inverse = (direction == 'north' || direction == 'south'); - - if (inverse) - { - sy = bounds.width / this.h0; - sx = bounds.height / this.w0; - - var delta = (bounds.width - bounds.height) / 2; - - x0 += delta; - y0 -= delta; - } - - if (this.aspect == 'fixed') - { - sy = Math.min(sx, sy); - sx = sy; - - // Centers the shape inside the available space - if (inverse) - { - x0 += (bounds.height - this.w0 * sx) / 2; - y0 += (bounds.width - this.h0 * sy) / 2; - } - else - { - x0 += (bounds.width - this.w0 * sx) / 2; - y0 += (bounds.height - this.h0 * sy) / 2; - } - } - - return new mxRectangle(x0, y0, sx, sy); -}; - -/** - * Function: drawNode - * - * Draws this stencil inside the given bounds. - */ -mxStencil.prototype.drawNode = function(canvas, state, node, aspect) -{ - var name = node.nodeName; - var x0 = aspect.x; - var y0 = aspect.y; - var sx = aspect.width; - var sy = aspect.height; - var minScale = Math.min(sx, sy); - - // LATER: Move to lookup table - if (name == 'save') - { - canvas.save(); - } - else if (name == 'restore') - { - canvas.restore(); - } - else if (name == 'path') - { - canvas.begin(); - - // Renders the elements inside the given path - var childNode = node.firstChild; - - while (childNode != null) - { - if (childNode.nodeType == mxConstants.NODETYPE_ELEMENT) - { - this.drawNode(canvas, state, childNode, aspect); - } - - childNode = childNode.nextSibling; - } - } - else if (name == 'close') - { - canvas.close(); - } - else if (name == 'move') - { - this.lastMoveX = x0 + Number(node.getAttribute('x')) * sx; - this.lastMoveY = y0 + Number(node.getAttribute('y')) * sy; - canvas.moveTo(this.lastMoveX, this.lastMoveY); - } - else if (name == 'line') - { - this.lastMoveX = x0 + Number(node.getAttribute('x')) * sx; - this.lastMoveY = y0 + Number(node.getAttribute('y')) * sy; - canvas.lineTo(this.lastMoveX, this.lastMoveY); - } - else if (name == 'quad') - { - this.lastMoveX = x0 + Number(node.getAttribute('x2')) * sx; - this.lastMoveY = y0 + Number(node.getAttribute('y2')) * sy; - canvas.quadTo(x0 + Number(node.getAttribute('x1')) * sx, - y0 + Number(node.getAttribute('y1')) * sy, - this.lastMoveX, this.lastMoveY); - } - else if (name == 'curve') - { - this.lastMoveX = x0 + Number(node.getAttribute('x3')) * sx; - this.lastMoveY = y0 + Number(node.getAttribute('y3')) * sy; - canvas.curveTo(x0 + Number(node.getAttribute('x1')) * sx, - y0 + Number(node.getAttribute('y1')) * sy, - x0 + Number(node.getAttribute('x2')) * sx, - y0 + Number(node.getAttribute('y2')) * sy, - this.lastMoveX, this.lastMoveY); - } - else if (name == 'arc') - { - // Arc from stencil is turned into curves in image output - var r1 = Number(node.getAttribute('rx')) * sx; - var r2 = Number(node.getAttribute('ry')) * sy; - var angle = Number(node.getAttribute('x-axis-rotation')); - var largeArcFlag = Number(node.getAttribute('large-arc-flag')); - var sweepFlag = Number(node.getAttribute('sweep-flag')); - var x = x0 + Number(node.getAttribute('x')) * sx; - var y = y0 + Number(node.getAttribute('y')) * sy; - - var curves = mxUtils.arcToCurves(this.lastMoveX, this.lastMoveY, r1, r2, angle, largeArcFlag, sweepFlag, x, y); - - for (var i = 0; i < curves.length; i += 6) - { - canvas.curveTo(curves[i], curves[i + 1], curves[i + 2], - curves[i + 3], curves[i + 4], curves[i + 5]); - - this.lastMoveX = curves[i + 4]; - this.lastMoveY = curves[i + 5]; - } - } - else if (name == 'rect') - { - canvas.rect(x0 + Number(node.getAttribute('x')) * sx, - y0 + Number(node.getAttribute('y')) * sy, - Number(node.getAttribute('w')) * sx, - Number(node.getAttribute('h')) * sy); - } - else if (name == 'roundrect') - { - var arcsize = node.getAttribute('arcsize'); - - if (arcsize == 0) - { - arcsize = mxConstants.RECTANGLE_ROUNDING_FACTOR * 100; - } - - var w = Number(node.getAttribute('w')) * sx; - var h = Number(node.getAttribute('h')) * sy; - var factor = Number(arcsize) / 100; - var r = Math.min(w * factor, h * factor); - - canvas.roundrect(x0 + Number(node.getAttribute('x')) * sx, - y0 + Number(node.getAttribute('y')) * sy, - w, h, r, r); - } - else if (name == 'ellipse') - { - canvas.ellipse(x0 + Number(node.getAttribute('x')) * sx, - y0 + Number(node.getAttribute('y')) * sy, - Number(node.getAttribute('w')) * sx, - Number(node.getAttribute('h')) * sy); - } - else if (name == 'image') - { - var src = this.evaluateAttribute(node, 'src', state); - - canvas.image(x0 + Number(node.getAttribute('x')) * sx, - y0 + Number(node.getAttribute('y')) * sy, - Number(node.getAttribute('w')) * sx, - Number(node.getAttribute('h')) * sy, - src, false, node.getAttribute('flipH') == '1', - node.getAttribute('flipV') == '1'); - } - else if (name == 'text') - { - var str = this.evaluateAttribute(node, 'str', state); - - canvas.text(x0 + Number(node.getAttribute('x')) * sx, - y0 + Number(node.getAttribute('y')) * sy, - 0, 0, str, node.getAttribute('align'), - node.getAttribute('valign'), - node.getAttribute('vertical')); - } - else if (name == 'include-shape') - { - var stencil = mxStencilRegistry.getStencil(node.getAttribute('name')); - - if (stencil != null) - { - var x = x0 + Number(node.getAttribute('x')) * sx; - var y = y0 + Number(node.getAttribute('y')) * sy; - var w = Number(node.getAttribute('w')) * sx; - var h = Number(node.getAttribute('h')) * sy; - - var tmp = new mxRectangle(x, y, w, h); - stencil.drawShape(canvas, state, tmp, true); - stencil.drawShape(canvas, state, tmp, false); - } - } - else if (name == 'fillstroke') - { - canvas.fillAndStroke(); - } - else if (name == 'fill') - { - canvas.fill(); - } - else if (name == 'stroke') - { - canvas.stroke(); - } - else if (name == 'strokewidth') - { - canvas.setStrokeWidth(Number(node.getAttribute('width')) * minScale); - } - else if (name == 'dashed') - { - canvas.setDashed(node.getAttribute('dashed') == '1'); - } - else if (name == 'dashpattern') - { - var value = node.getAttribute('pattern'); - - if (value != null) - { - var tmp = value.split(' '); - var pat = []; - - for (var i = 0; i < tmp.length; i++) - { - if (tmp[i].length > 0) - { - pat.push(Number(tmp[i]) * minScale); - } - } - - value = pat.join(' '); - canvas.setDashPattern(value); - } - } - else if (name == 'strokecolor') - { - canvas.setStrokeColor(node.getAttribute('color')); - } - else if (name == 'linecap') - { - canvas.setLineCap(node.getAttribute('cap')); - } - else if (name == 'linejoin') - { - canvas.setLineJoin(node.getAttribute('join')); - } - else if (name == 'miterlimit') - { - canvas.setMiterLimit(Number(node.getAttribute('limit'))); - } - else if (name == 'fillcolor') - { - canvas.setFillColor(node.getAttribute('color')); - } - else if (name == 'fontcolor') - { - canvas.setFontColor(node.getAttribute('color')); - } - else if (name == 'fontstyle') - { - canvas.setFontStyle(node.getAttribute('style')); - } - else if (name == 'fontfamily') - { - canvas.setFontFamily(node.getAttribute('family')); - } - else if (name == 'fontsize') - { - canvas.setFontSize(Number(node.getAttribute('size')) * minScale); - } -}; diff --git a/src/js/shape/mxStencilRegistry.js b/src/js/shape/mxStencilRegistry.js deleted file mode 100644 index 7621573..0000000 --- a/src/js/shape/mxStencilRegistry.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * $Id: mxStencilRegistry.js,v 1.2 2011-07-15 12:57:50 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - * - * Code to add stencils. - * - * (code) - * var req = mxUtils.load('test/stencils.xml'); - * var root = req.getDocumentElement(); - * var shape = root.firstChild; - * - * while (shape != null) - * { - * if (shape.nodeType == mxConstants.NODETYPE_ELEMENT) - * { - * mxStencilRegistry.addStencil(shape.getAttribute('name'), new mxStencil(shape)); - * } - * - * shape = shape.nextSibling; - * } - * (end) - */ -var mxStencilRegistry = -{ - /** - * Class: mxStencilRegistry - * - * A singleton class that provides a registry for stencils and the methods - * for painting those stencils onto a canvas or into a DOM. - */ - stencils: [], - - /** - * Function: addStencil - * - * Adds the given <mxStencil>. - */ - addStencil: function(name, stencil) - { - mxStencilRegistry.stencils[name] = stencil; - }, - - /** - * Function: getStencil - * - * Returns the <mxStencil> for the given name. - */ - getStencil: function(name) - { - return mxStencilRegistry.stencils[name]; - } - -}; diff --git a/src/js/shape/mxStencilShape.js b/src/js/shape/mxStencilShape.js deleted file mode 100644 index 9c95f8b..0000000 --- a/src/js/shape/mxStencilShape.js +++ /dev/null @@ -1,209 +0,0 @@ -/** - * $Id: mxStencilShape.js,v 1.10 2012-07-16 10:22:44 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxStencilShape - * - * Implements a shape based on a <mxStencil>. - * - * Constructor: mxStencilShape - * - * Constructs a new generic shape. - */ -function mxStencilShape(stencil) -{ - this.stencil = stencil; -}; - -/** - * Extends mxShape. - */ -mxStencilShape.prototype = new mxShape(); -mxStencilShape.prototype.constructor = mxStencilShape; - -/** - * Variable: mixedModeHtml - * - * Always prefers VML in mixed mode for stencil shapes. Default is false. - */ -mxStencilShape.prototype.mixedModeHtml = false; - -/** - * Variable: preferModeHtml - * - * Always prefers VML in prefer HTML mode for stencil shapes. Default is false. - */ -mxStencilShape.prototype.preferModeHtml = false; - -/** - * Variable: stencil - * - * Holds the <mxStencil> that defines the shape. - */ -mxStencilShape.prototype.stencil = null; - -/** - * Variable: state - * - * Holds the <mxCellState> associated with this shape. - */ -mxStencilShape.prototype.state = null; - -/** - * Variable: vmlScale - * - * Renders VML with a scale of 4. - */ -mxStencilShape.prototype.vmlScale = 4; - -/** - * Function: apply - * - * Extends <mxShape> apply to keep a reference to the <mxCellState>. - * - * Parameters: - * - * state - <mxCellState> of the corresponding cell. - */ -mxStencilShape.prototype.apply = function(state) -{ - this.state = state; - mxShape.prototype.apply.apply(this, arguments); -}; - -/** - * Function: createSvg - * - * Creates and returns the SVG node(s) to represent this shape. - */ -mxStencilShape.prototype.createSvg = function() -{ - var node = document.createElementNS(mxConstants.NS_SVG, 'g'); - this.configureSvgShape(node); - - return node; -}; - -/** - * Function: configureHtmlShape - * - * Overrides method to set the overflow style to visible. - */ -mxStencilShape.prototype.configureHtmlShape = function(node) -{ - mxShape.prototype.configureHtmlShape.apply(this, arguments); - - if (!mxUtils.isVml(node)) - { - node.style.overflow = 'visible'; - } -}; - -/** - * Function: createVml - * - * Creates and returns the VML node to represent this shape. - */ -mxStencilShape.prototype.createVml = function() -{ - var name = (document.documentMode == 8) ? 'div' : 'v:group'; - var node = document.createElement(name); - this.configureTransparentBackground(node); - node.style.position = 'absolute'; - - return node; -}; - -/** - * Function: configureVmlShape - * - * Configures the specified VML node by applying the current color, - * bounds, shadow, opacity etc. - */ -mxStencilShape.prototype.configureVmlShape = function(node) -{ - // do nothing -}; - -/** - * Function: redraw - * - * Creates and returns the SVG node(s) to represent this shape. - */ -mxStencilShape.prototype.redraw = function() -{ - this.updateBoundingBox(); - - if (this.dialect == mxConstants.DIALECT_SVG) - { - this.redrawShape(); - } - else - { - this.node.style.visibility = 'hidden'; - this.redrawShape(); - this.node.style.visibility = 'visible'; - } -}; - -/** - * Function: redrawShape - * - * Updates the SVG or VML shape. - */ -mxStencilShape.prototype.redrawShape = function() -{ - // LATER: Update existing DOM nodes to improve repaint performance - if (this.dialect != mxConstants.DIALECT_SVG) - { - this.node.style.left = Math.round(this.bounds.x) + 'px'; - this.node.style.top = Math.round(this.bounds.y) + 'px'; - var w = Math.round(this.bounds.width); - var h = Math.round(this.bounds.height); - this.node.style.width = w + 'px'; - this.node.style.height = h + 'px'; - - var node = this.node; - - // Workaround for VML rendering bug in IE8 standards mode where all VML must be - // parsed via assigning the innerHTML of the parent HTML node to keep all event - // handlers referencing node and support rotation via v:group parent element. - if (this.node.nodeName == 'DIV') - { - node = document.createElement('v:group'); - node.style.position = 'absolute'; - node.style.left = '0px'; - node.style.top = '0px'; - node.style.width = w + 'px'; - node.style.height = h + 'px'; - } - else - { - node.innerHTML = ''; - } - - if (mxUtils.isVml(node)) - { - var s = (document.documentMode != 8) ? this.vmlScale : 1; - node.coordsize = (w * s) + ',' + (h * s); - } - - this.stencil.renderDom(this, this.bounds, node); - - if(this.node != node) - { - // Forces parsing in IE8 standards mode - this.node.innerHTML = node.outerHTML; - } - } - else - { - while (this.node.firstChild != null) - { - this.node.removeChild(this.node.firstChild); - } - - this.stencil.renderDom(this, this.bounds, this.node); - } -}; diff --git a/src/js/shape/mxSwimlane.js b/src/js/shape/mxSwimlane.js deleted file mode 100644 index 22720fd..0000000 --- a/src/js/shape/mxSwimlane.js +++ /dev/null @@ -1,553 +0,0 @@ -/** - * $Id: mxSwimlane.js,v 1.43 2011-11-04 13:54:50 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxSwimlane - * - * Extends <mxShape> to implement a swimlane shape. - * This shape is registered under <mxConstants.SHAPE_SWIMLANE> - * in <mxCellRenderer>. - * - * Constructor: mxSwimlane - * - * Constructs a new swimlane shape. - * - * Parameters: - * - * bounds - <mxRectangle> that defines the bounds. This is stored in - * <mxShape.bounds>. - * fill - String that defines the fill color. This is stored in <fill>. - * stroke - String that defines the stroke color. This is stored in <stroke>. - * strokewidth - Optional integer that defines the stroke width. Default is - * 1. This is stored in <strokewidth>. - */ -function mxSwimlane(bounds, fill, stroke, strokewidth) -{ - this.bounds = bounds; - this.fill = fill; - this.stroke = stroke; - this.strokewidth = (strokewidth != null) ? strokewidth : 1; -}; - -/** - * Extends mxShape. - */ -mxSwimlane.prototype = new mxShape(); -mxSwimlane.prototype.constructor = mxSwimlane; - -/** - * Variable: vmlNodes - * - * Adds local references to <mxShape.vmlNodes>. - */ -mxSwimlane.prototype.vmlNodes = mxSwimlane.prototype.vmlNodes.concat(['label', 'content', 'imageNode', 'separator']); - -/** - * Variable: imageSize - * - * Default imagewidth and imageheight if an image but no imagewidth - * and imageheight are defined in the style. Value is 16. - */ -mxSwimlane.prototype.imageSize = 16; - -/** - * Variable: mixedModeHtml - * - * Overrides the parent value with false, meaning it will - * draw in VML in mixed Html mode. This is for better - * handling of event-transparency of the content area. - */ -mxSwimlane.prototype.mixedModeHtml = false; - -/** - * Variable: preferModeHtml - * - * Overrides the parent value with false, meaning it will - * draw as VML in prefer Html mode. This is for better - * handling of event-transparency of the content area. - */ -mxRhombus.prototype.preferModeHtml = false; - -/** - * Function: createHtml - * - * Creates and returns the HTML node to represent this shape. - */ -mxSwimlane.prototype.createHtml = function() -{ - var node = document.createElement('DIV'); - this.configureHtmlShape(node); - node.style.background = ''; - node.style.backgroundColor = ''; - node.style.borderStyle = 'none'; - - // Adds a node that will contain the text label - this.label = document.createElement('DIV'); - this.configureHtmlShape(this.label); - node.appendChild(this.label); - - // Adds a node for the content area of the swimlane - this.content = document.createElement('DIV'); - this.configureHtmlShape(this.content); - this.content.style.backgroundColor = ''; - - // Sets border styles depending on orientation - if (mxUtils.getValue(this.style, mxConstants.STYLE_HORIZONTAL, true)) - { - this.content.style.borderTopStyle = 'none'; - } - else - { - this.content.style.borderLeftStyle = 'none'; - } - - this.content.style.cursor = 'default'; - node.appendChild(this.content); - - // Adds a node for the separator - var color = this.style[mxConstants.STYLE_SEPARATORCOLOR]; - - if (color != null) - { - this.separator = document.createElement('DIV'); - this.separator.style.borderColor = color; - this.separator.style.borderLeftStyle = 'dashed'; - node.appendChild(this.separator); - } - - // Adds a node for the image - if (this.image != null) - { - this.imageNode = mxUtils.createImage(this.image); - this.configureHtmlShape(this.imageNode); - this.imageNode.style.borderStyle = 'none'; - node.appendChild(this.imageNode); - } - - return node; -}; - -/** - * Function: reconfigure - * - * Overrides to avoid filled content area in HTML and updates the shadow - * in SVG. - */ -mxSwimlane.prototype.reconfigure = function(node) -{ - mxShape.prototype.reconfigure.apply(this, arguments); - - if (this.dialect == mxConstants.DIALECT_SVG) - { - if (this.shadowNode != null) - { - this.updateSvgShape(this.shadowNode); - - if (mxUtils.getValue(this.style, mxConstants.STYLE_HORIZONTAL, true)) - { - this.shadowNode.setAttribute('height', this.startSize*this.scale); - } - else - { - this.shadowNode.setAttribute('width', this.startSize*this.scale); - } - } - } - else if (!mxUtils.isVml(this.node)) - { - this.node.style.background = ''; - this.node.style.backgroundColor = ''; - } -}; - -/** - * Function: redrawHtml - * - * Updates the HTML node(s) to reflect the latest bounds and scale. - */ -mxSwimlane.prototype.redrawHtml = function() -{ - this.updateHtmlShape(this.node); - this.node.style.background = ''; - this.node.style.backgroundColor = ''; - this.startSize = parseInt(mxUtils.getValue(this.style, - mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE)); - this.updateHtmlShape(this.label); - this.label.style.top = '0px'; - this.label.style.left = '0px'; - - if (mxUtils.getValue(this.style, mxConstants.STYLE_HORIZONTAL, true)) - { - this.startSize = Math.min(this.startSize, this.bounds.height); - this.label.style.height = (this.startSize * this.scale)+'px'; // relative - this.updateHtmlShape(this.content); - this.content.style.background = ''; - this.content.style.backgroundColor = ''; - - var h = this.startSize*this.scale; - - this.content.style.top = h+'px'; - this.content.style.left = '0px'; - this.content.style.height = Math.max(1, this.bounds.height - h)+'px'; - - if (this.separator != null) - { - this.separator.style.left = Math.round(this.bounds.width)+'px'; - this.separator.style.top = Math.round(this.startSize*this.scale)+'px'; - this.separator.style.width = '1px'; - this.separator.style.height = Math.round(this.bounds.height)+'px'; - this.separator.style.borderWidth = Math.round(this.scale)+'px'; - } - - if (this.imageNode != null) - { - this.imageNode.style.left = (this.bounds.width-this.imageSize-4)+'px'; - this.imageNode.style.top = '0px'; - // TODO: Use imageWidth and height from style if available - this.imageNode.style.width = Math.round(this.imageSize*this.scale)+'px'; - this.imageNode.style.height = Math.round(this.imageSize*this.scale)+'px'; - } - } - else - { - this.startSize = Math.min(this.startSize, this.bounds.width); - this.label.style.width = (this.startSize * this.scale)+'px'; // relative - this.updateHtmlShape(this.content); - this.content.style.background = ''; - this.content.style.backgroundColor = ''; - - var w = this.startSize*this.scale; - - this.content.style.top = '0px'; - this.content.style.left = w+'px'; - this.content.style.width = Math.max(0, this.bounds.width - w)+'px'; - - if (this.separator != null) - { - this.separator.style.left = Math.round(this.startSize*this.scale)+'px'; - this.separator.style.top = Math.round(this.bounds.height)+'px'; - this.separator.style.width = Math.round(this.bounds.width)+'px'; - this.separator.style.height = '1px'; - } - - if (this.imageNode != null) - { - this.imageNode.style.left = (this.bounds.width-this.imageSize-4)+'px'; - this.imageNode.style.top = '0px'; - this.imageNode.style.width = this.imageSize*this.scale+'px'; - this.imageNode.style.height = this.imageSize*this.scale+'px'; - } - } -}; - -/** - * Function: createVml - * - * Creates and returns the VML node(s) to represent this shape. - */ -mxSwimlane.prototype.createVml = function() -{ - var node = document.createElement('v:group'); - var name = (this.isRounded) ? 'v:roundrect' : 'v:rect'; - this.label = document.createElement(name); - - // First configure the label with all settings - this.configureVmlShape(this.label); - - if (this.isRounded) - { - this.label.setAttribute('arcsize', '20%'); - } - - // Disables stuff and configures the rest - this.isShadow = false; - this.configureVmlShape(node); - node.coordorigin = '0,0'; - node.appendChild(this.label); - - this.content = document.createElement(name); - - var tmp = this.fill; - this.fill = null; - - this.configureVmlShape(this.content); - node.style.background = ''; - - if (this.isRounded) - { - this.content.setAttribute('arcsize', '4%'); - } - - this.fill = tmp; - this.content.style.borderBottom = '0px'; - - node.appendChild(this.content); - - var color = this.style[mxConstants.STYLE_SEPARATORCOLOR]; - - if (color != null) - { - this.separator = document.createElement('v:shape'); - this.separator.style.position = 'absolute'; - this.separator.strokecolor = color; - - var strokeNode = document.createElement('v:stroke'); - strokeNode.dashstyle = '2 2'; - this.separator.appendChild(strokeNode); - - node.appendChild(this.separator); - } - - if (this.image != null) - { - this.imageNode = document.createElement('v:image'); - this.imageNode.src = this.image; - this.configureVmlShape(this.imageNode); - this.imageNode.stroked = 'false'; - - node.appendChild(this.imageNode); - } - - return node; -}; - -/** - * Function: redrawVml - * - * Updates the VML node(s) to reflect the latest bounds and scale. - */ -mxSwimlane.prototype.redrawVml = function() -{ - var x = Math.round(this.bounds.x); - var y = Math.round(this.bounds.y); - var w = Math.round(this.bounds.width); - var h = Math.round(this.bounds.height); - - this.updateVmlShape(this.node); - this.node.coordsize = w + ',' + h; - - this.updateVmlShape(this.label); - this.label.style.top = '0px'; - this.label.style.left = '0px'; - this.label.style.rotation = null; - - this.startSize = parseInt(mxUtils.getValue(this.style, - mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE)); - var start = Math.round(this.startSize * this.scale); - - if (this.separator != null) - { - this.separator.coordsize = w + ',' + h; - this.separator.style.left = x + 'px'; - this.separator.style.top = y + 'px'; - this.separator.style.width = w + 'px'; - this.separator.style.height = h + 'px'; - } - - if (mxUtils.getValue(this.style, mxConstants.STYLE_HORIZONTAL, true)) - { - start = Math.min(start, this.bounds.height); - this.label.style.height = start + 'px'; // relative - this.updateVmlShape(this.content); - this.content.style.background = ''; - this.content.style.top = start + 'px'; - this.content.style.left = '0px'; - this.content.style.height = Math.max(0, h - start)+'px'; - - if (this.separator != null) - { - var d = 'm ' + (w - x) + ' ' + (start - y) + - ' l ' + (w - x) + ' ' + (h - y) + ' e'; - this.separator.path = d; - } - - if (this.imageNode != null) - { - var img = Math.round(this.imageSize*this.scale); - - this.imageNode.style.left = (w-img-4)+'px'; - this.imageNode.style.top = '0px'; - this.imageNode.style.width = img + 'px'; - this.imageNode.style.height = img + 'px'; - } - } - else - { - start = Math.min(start, this.bounds.width); - this.label.style.width = start + 'px'; // relative - this.updateVmlShape(this.content); - this.content.style.background = ''; - this.content.style.top = '0px'; - this.content.style.left = start + 'px'; - this.content.style.width = Math.max(0, w - start) + 'px'; - - if (this.separator != null) - { - var d = 'm ' + (start - x) + ' ' + (h - y) + - ' l ' + (w - x) + ' ' + (h - y) + ' e'; - this.separator.path = d; - } - - if (this.imageNode != null) - { - var img = Math.round(this.imageSize * this.scale); - - this.imageNode.style.left = (w - img - 4)+'px'; - this.imageNode.style.top = '0px'; - this.imageNode.style.width = img + 'px'; - this.imageNode.style.height = img + 'px'; - } - } - - this.content.style.rotation = null; -}; - -/** - * Function: createSvg - * - * Creates and returns the SVG node(s) to represent this shape. - */ -mxSwimlane.prototype.createSvg = function() -{ - var node = this.createSvgGroup('rect'); - - if (this.isRounded) - { - this.innerNode.setAttribute('rx', 10); - this.innerNode.setAttribute('ry', 10); - } - - this.content = document.createElementNS(mxConstants.NS_SVG, 'path'); - this.configureSvgShape(this.content); - this.content.setAttribute('fill', 'none'); - - if (this.isRounded) - { - this.content.setAttribute('rx', 10); - this.content.setAttribute('ry', 10); - } - - node.appendChild(this.content); - var color = this.style[mxConstants.STYLE_SEPARATORCOLOR]; - - if (color != null) - { - this.separator = document.createElementNS(mxConstants.NS_SVG, 'line'); - - this.separator.setAttribute('stroke', color); - this.separator.setAttribute('fill', 'none'); - this.separator.setAttribute('stroke-dasharray', '2, 2'); - - node.appendChild(this.separator); - } - - if (this.image != null) - { - this.imageNode = document.createElementNS(mxConstants.NS_SVG, 'image'); - - this.imageNode.setAttributeNS(mxConstants.NS_XLINK, 'href', this.image); - this.configureSvgShape(this.imageNode); - - node.appendChild(this.imageNode); - } - - return node; -}; - -/** - * Function: redrawSvg - * - * Updates the SVG node(s) to reflect the latest bounds and scale. - */ -mxSwimlane.prototype.redrawSvg = function() -{ - var tmp = this.isRounded; - this.isRounded = false; - - this.updateSvgShape(this.innerNode); - this.updateSvgShape(this.content); - var horizontal = mxUtils.getValue(this.style, mxConstants.STYLE_HORIZONTAL, true); - this.startSize = parseInt(mxUtils.getValue(this.style, - mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE)); - var ss = this.startSize * this.scale; - - // Updates the size of the shadow node - if (this.shadowNode != null) - { - this.updateSvgShape(this.shadowNode); - - if (horizontal) - { - this.shadowNode.setAttribute('height', ss); - } - else - { - this.shadowNode.setAttribute('width', ss); - } - } - - this.isRounded = tmp; - - this.content.removeAttribute('x'); - this.content.removeAttribute('y'); - this.content.removeAttribute('width'); - this.content.removeAttribute('height'); - - var crisp = (this.crisp && mxClient.IS_IE) ? 0.5 : 0; - var x = Math.round(this.bounds.x) + crisp; - var y = Math.round(this.bounds.y) + crisp; - var w = Math.round(this.bounds.width); - var h = Math.round(this.bounds.height); - - if (horizontal) - { - ss = Math.min(ss, h); - this.innerNode.setAttribute('height', ss); - var points = 'M ' + x + ' ' + (y + ss) + - ' l 0 ' + (h - ss) + ' l ' + w + ' 0' + - ' l 0 ' + (ss - h); - this.content.setAttribute('d', points); - - if (this.separator != null) - { - this.separator.setAttribute('x1', x + w); - this.separator.setAttribute('y1', y + ss); - this.separator.setAttribute('x2', x + w); - this.separator.setAttribute('y2', y + h); - } - - if (this.imageNode != null) - { - this.imageNode.setAttribute('x', x + w - this.imageSize - 4); - this.imageNode.setAttribute('y', y); - this.imageNode.setAttribute('width', this.imageSize * this.scale + 'px'); - this.imageNode.setAttribute('height', this.imageSize * this.scale + 'px'); - } - } - else - { - ss = Math.min(ss, w); - this.innerNode.setAttribute('width', ss); - var points = 'M ' + (x + ss) + ' ' + y + - ' l ' + (w - ss) + ' 0' + ' l 0 ' + h + - ' l ' + (ss - w) + ' 0'; - this.content.setAttribute('d', points); - - if (this.separator != null) - { - this.separator.setAttribute('x1', x + ss); - this.separator.setAttribute('y1', y + h); - this.separator.setAttribute('x2', x + w); - this.separator.setAttribute('y2', y + h); - } - - if (this.imageNode != null) - { - this.imageNode.setAttribute('x', x + w - this.imageSize - 4); - this.imageNode.setAttribute('y', y); - this.imageNode.setAttribute('width', this.imageSize * this.scale + 'px'); - this.imageNode.setAttribute('height', this.imageSize * this.scale + 'px'); - } - } -}; diff --git a/src/js/shape/mxText.js b/src/js/shape/mxText.js deleted file mode 100644 index de44b59..0000000 --- a/src/js/shape/mxText.js +++ /dev/null @@ -1,1811 +0,0 @@ -/** - * $Id: mxText.js,v 1.174 2012-09-27 10:20:30 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxText - * - * Extends <mxShape> to implement a text shape. To change vertical text from - * bottom to top to top to bottom, the following code can be used: - * - * (code) - * mxText.prototype.ieVerticalFilter = 'progid:DXImageTransform.Microsoft.BasicImage(rotation=1)'; - * mxText.prototype.verticalTextDegree = 90; - * - * mxText.prototype.getVerticalOffset = function(offset) - * { - * return new mxPoint(-offset.y, offset.x); - * }; - * (end) - * - * Constructor: mxText - * - * Constructs a new text shape. - * - * Parameters: - * - * value - String that represents the text to be displayed. This is stored in - * <value>. - * bounds - <mxRectangle> that defines the bounds. This is stored in - * <mxShape.bounds>. - * align - Specifies the horizontal alignment. Default is ''. This is stored in - * <align>. - * valign - Specifies the vertical alignment. Default is ''. This is stored in - * <valign>. - * color - String that specifies the text color. Default is 'black'. This is - * stored in <color>. - * family - String that specifies the font family. Default is - * <mxConstants.DEFAULT_FONTFAMILY>. This is stored in <family>. - * size - Integer that specifies the font size. Default is - * <mxConstants.DEFAULT_FONTSIZE>. This is stored in <size>. - * fontStyle - Specifies the font style. Default is 0. This is stored in - * <fontStyle>. - * spacing - Integer that specifies the global spacing. Default is 2. This is - * stored in <spacing>. - * spacingTop - Integer that specifies the top spacing. Default is 0. The - * sum of the spacing and this is stored in <spacingTop>. - * spacingRight - Integer that specifies the right spacing. Default is 0. The - * sum of the spacing and this is stored in <spacingRight>. - * spacingBottom - Integer that specifies the bottom spacing. Default is 0.The - * sum of the spacing and this is stored in <spacingBottom>. - * spacingLeft - Integer that specifies the left spacing. Default is 0. The - * sum of the spacing and this is stored in <spacingLeft>. - * horizontal - Boolean that specifies if the label is horizontal. Default is - * true. This is stored in <horizontal>. - * background - String that specifies the background color. Default is null. - * This is stored in <background>. - * border - String that specifies the label border color. Default is null. - * This is stored in <border>. - * wrap - Specifies if word-wrapping should be enabled. Default is false. - * This is stored in <wrap>. - * clipped - Specifies if the label should be clipped. Default is false. - * This is stored in <clipped>. - * overflow - Value of the overflow style. Default is 'visible'. - */ -function mxText(value, bounds, align, valign, color, - family, size, fontStyle, spacing, spacingTop, spacingRight, - spacingBottom, spacingLeft, horizontal, background, border, - wrap, clipped, overflow, labelPadding) -{ - this.value = value; - this.bounds = bounds; - this.color = (color != null) ? color : 'black'; - this.align = (align != null) ? align : ''; - this.valign = (valign != null) ? valign : ''; - this.family = (family != null) ? family : mxConstants.DEFAULT_FONTFAMILY; - this.size = (size != null) ? size : mxConstants.DEFAULT_FONTSIZE; - this.fontStyle = (fontStyle != null) ? fontStyle : 0; - this.spacing = parseInt(spacing || 2); - this.spacingTop = this.spacing + parseInt(spacingTop || 0); - this.spacingRight = this.spacing + parseInt(spacingRight || 0); - this.spacingBottom = this.spacing + parseInt(spacingBottom || 0); - this.spacingLeft = this.spacing + parseInt(spacingLeft || 0); - this.horizontal = (horizontal != null) ? horizontal : true; - this.background = background; - this.border = border; - this.wrap = (wrap != null) ? wrap : false; - this.clipped = (clipped != null) ? clipped : false; - this.overflow = (overflow != null) ? overflow : 'visible'; - this.labelPadding = (labelPadding != null) ? labelPadding : 0; -}; - -/** - * Extends mxShape. - */ -mxText.prototype = new mxShape(); -mxText.prototype.constructor = mxText; - -/** - * Variable: replaceLinefeeds - * - * Specifies if linefeeds in HTML labels should be replaced with BR tags. - * Default is true. This is also used in <mxImageExport> to export the label. - */ -mxText.prototype.replaceLinefeeds = true; - -/** - * Variable: ieVerticalFilter - * - * Holds the filter definition for vertical text in IE. Default is - * progid:DXImageTransform.Microsoft.BasicImage(rotation=3). - */ -mxText.prototype.ieVerticalFilter = 'progid:DXImageTransform.Microsoft.BasicImage(rotation=3)'; - -/** - * Variable: verticalTextDegree - * - * Specifies the degree to be used for vertical text. Default is -90. - */ -mxText.prototype.verticalTextDegree = -90; - -/** - * Variable: forceIgnoreStringSize - * - * Specifies if the string size should always be ignored. Default is false. - * This can be used to improve rendering speed in slow browsers. This can be - * used if all labels are smaller than the vertex width. String sizes are - * ignored by default for labels which are left aligned with no background and - * border or if the overflow is set to fill. - */ -mxText.prototype.forceIgnoreStringSize = false; - -/** - * Function: isStyleSet - * - * Returns true if the given font style (bold, italic etc) - * is true in this shape's fontStyle. - * - * Parameters: - * - * style - Fontstyle constant from <mxConstants>. - */ -mxText.prototype.isStyleSet = function(style) -{ - return (this.fontStyle & style) == style; -}; - -/** - * Function: create - * - * Override to create HTML regardless of gradient and - * rounded property. - */ -mxText.prototype.create = function(container) -{ - var node = null; - - if (this.dialect == mxConstants.DIALECT_SVG) - { - node = this.createSvg(); - } - else if (this.dialect == mxConstants.DIALECT_STRICTHTML || - this.dialect == mxConstants.DIALECT_PREFERHTML || - !mxUtils.isVml(container)) - { - if (mxClient.IS_SVG && !mxClient.NO_FO) - { - node = this.createForeignObject(); - } - else - { - node = this.createHtml(); - } - } - else - { - node = this.createVml(); - } - - return node; -}; - -/** - * Function: updateBoundingBox - * - * Overrides method to do nothing. - */ -mxText.prototype.updateBoundingBox = function() -{ - // do nothing -}; - -/** - * Function: createForeignObject - * - * Creates and returns the foreignObject node to represent this shape. - */ -mxText.prototype.createForeignObject = function() -{ - var node = document.createElementNS(mxConstants.NS_SVG, 'g'); - - var fo = document.createElementNS(mxConstants.NS_SVG, 'foreignObject'); - fo.setAttribute('pointer-events', 'fill'); - - // Ignored in FF - if (this.overflow == 'hidden') - { - fo.style.overflow = 'hidden'; - } - else - { - // Fill and default are visible - fo.style.overflow = 'visible'; - } - - var body = document.createElement('div'); - body.style.margin = '0px'; - body.style.height = '100%'; - - fo.appendChild(body); - node.appendChild(fo); - - return node; -}; - -/** - * Function: createHtml - * - * Creates and returns the HTML node to represent this shape. - */ -mxText.prototype.createHtml = function() -{ - var table = this.createHtmlTable(); - table.style.position = 'absolute'; - - return table; -}; - -/** - * Function: createVml - * - * Creates and returns the VML node(s) to represent this shape. - */ -mxText.prototype.createVml = function() -{ - return document.createElement('v:textbox'); -}; - -/** - * Function: redrawHtml - * - * Updates the HTML node(s) to reflect the latest bounds and scale. - */ -mxText.prototype.redrawHtml = function() -{ - this.redrawVml(); -}; - -/** - * Function: getOffset - * - * Returns the description of the space between the <bounds> size and the label - * size as an <mxPoint>. - */ -mxText.prototype.getOffset = function(outerWidth, outerHeight, actualWidth, actualHeight, horizontal) -{ - horizontal = (horizontal != null) ? horizontal : this.horizontal; - - var tmpalign = (horizontal) ? this.align : this.valign; - var tmpvalign = (horizontal) ? this.valign : this.align; - var dx = actualWidth - outerWidth; - var dy = actualHeight - outerHeight; - - if (tmpalign == mxConstants.ALIGN_CENTER || tmpalign == mxConstants.ALIGN_MIDDLE) - { - dx = Math.round(dx / 2); - } - else if (tmpalign == mxConstants.ALIGN_LEFT || tmpalign === mxConstants.ALIGN_TOP) - { - dx = (horizontal) ? 0 : (actualWidth - actualHeight) / 2; - } - else if (!horizontal) // BOTTOM - { - dx = (actualWidth + actualHeight) / 2 - outerWidth; - } - - if (tmpvalign == mxConstants.ALIGN_MIDDLE || tmpvalign == mxConstants.ALIGN_CENTER) - { - dy = Math.round(dy / 2); - } - else if (tmpvalign == mxConstants.ALIGN_TOP || tmpvalign == mxConstants.ALIGN_LEFT) - { - dy = (horizontal) ? 0 : (actualHeight + actualWidth) / 2 - outerHeight; - } - else if (!horizontal) // RIGHT - { - dy = (actualHeight - actualWidth) / 2; - } - - return new mxPoint(dx, dy); -}; - -/** - * Function: getSpacing - * - * Returns the spacing as an <mxPoint>. - */ -mxText.prototype.getSpacing = function(horizontal) -{ - horizontal = (horizontal != null) ? horizontal : this.horizontal; - - var dx = 0; - var dy = 0; - - if (this.align == mxConstants.ALIGN_CENTER) - { - dx = (this.spacingLeft - this.spacingRight) / 2; - } - else if (this.align == mxConstants.ALIGN_RIGHT) - { - dx = -this.spacingRight; - } - else - { - dx = this.spacingLeft; - } - - if (this.valign == mxConstants.ALIGN_MIDDLE) - { - dy = (this.spacingTop - this.spacingBottom) / 2; - } - else if (this.valign == mxConstants.ALIGN_BOTTOM) - { - dy = -this.spacingBottom; - } - else - { - dy = this.spacingTop; - } - - return (horizontal) ? new mxPoint(dx, dy) : new mxPoint(dy, dx); -}; - -/** - * Function: createHtmlTable - * - * Creates and returns a HTML table with a table body and a single row with a - * single cell. - */ -mxText.prototype.createHtmlTable = function() -{ - var table = document.createElement('table'); - table.style.borderCollapse = 'collapse'; - var tbody = document.createElement('tbody'); - var tr = document.createElement('tr'); - var td = document.createElement('td'); - - // Workaround for ignored table height in IE9 standards mode - if (document.documentMode >= 9) - { - // FIXME: Ignored in print preview for IE9 standards mode - td.style.height = '100%'; - } - - tr.appendChild(td); - tbody.appendChild(tr); - table.appendChild(tbody); - - return table; -}; - -/** - * Function: updateTableStyle - * - * Updates the style of the given HTML table and the value - * within the table. - */ -mxText.prototype.updateHtmlTable = function(table, scale) -{ - scale = (scale != null) ? scale : 1; - var td = table.firstChild.firstChild.firstChild; - - // Reset of width required to measure actual width after word wrap - if (this.wrap) - { - table.style.width = ''; - } - - // Updates the value - if (mxUtils.isNode(this.value)) - { - if (td.firstChild != this.value) - { - if (td.firstChild != null) - { - td.removeChild(td.firstChild); - } - - td.appendChild(this.value); - } - } - else - { - if (this.lastValue != this.value) - { - td.innerHTML = (this.replaceLinefeeds) ? this.value.replace(/\n/g, '<br/>') : this.value; - this.lastValue = this.value; - } - } - - // Font style - var fontSize = Math.round(this.size * scale); - - if (fontSize <= 0) - { - table.style.visibility = 'hidden'; - } - else - { - // Do not use visible here as it will clone - // all labels while panning in IE - table.style.visibility = ''; - } - - table.style.fontSize = fontSize + 'px'; - table.style.color = this.color; - table.style.fontFamily = this.family; - - // Bold - if (this.isStyleSet(mxConstants.FONT_BOLD)) - { - table.style.fontWeight = 'bold'; - } - else - { - table.style.fontWeight = 'normal'; - } - - // Italic - if (this.isStyleSet(mxConstants.FONT_ITALIC)) - { - table.style.fontStyle = 'italic'; - } - else - { - table.style.fontStyle = ''; - } - - // Underline - if (this.isStyleSet(mxConstants.FONT_UNDERLINE)) - { - table.style.textDecoration = 'underline'; - } - else - { - table.style.textDecoration = ''; - } - - // Font shadow (only available in IE) - if (mxClient.IS_IE) - { - if (this.isStyleSet(mxConstants.FONT_SHADOW)) - { - td.style.filter = 'Shadow(Color=#666666,'+'Direction=135,Strength=%)'; - } - else - { - td.style.removeAttribute('filter'); - } - } - - // Horizontal and vertical alignment - td.style.textAlign = - (this.align == mxConstants.ALIGN_RIGHT) ? 'right' : - ((this.align == mxConstants.ALIGN_CENTER) ? 'center' : - 'left'); - td.style.verticalAlign = - (this.valign == mxConstants.ALIGN_BOTTOM) ? 'bottom' : - ((this.valign == mxConstants.ALIGN_MIDDLE) ? 'middle' : - 'top'); - - // Background style (Must use TD not TABLE for Firefox when rotated) - if (this.value.length > 0 && this.background != null) - { - td.style.background = this.background; - } - else - { - td.style.background = ''; - } - - td.style.padding = this.labelPadding + 'px'; - - if (this.value.length > 0 && this.border != null) - { - table.style.borderColor = this.border; - table.style.borderWidth = '1px'; - table.style.borderStyle = 'solid'; - } - else - { - table.style.borderStyle = 'none'; - } -}; - -/** - * Function: getTableSize - * - * Returns the actual size of the table. - */ -mxText.prototype.getTableSize = function(table) -{ - return new mxRectangle(0, 0, table.offsetWidth, table.offsetHeight); -}; - -/** - * Function: updateTableWidth - * - * Updates the width of the given HTML table. - */ -mxText.prototype.updateTableWidth = function(table) -{ - var td = table.firstChild.firstChild.firstChild; - - // Word-wrap for vertices (not edges) and only if not - // just getting the bounding box in SVG - if (this.wrap && this.bounds.width > 0 && this.dialect != mxConstants.DIALECT_SVG) - { - // Makes sure the label is not wrapped when measuring full length - td.style.whiteSpace = 'nowrap'; - var size = this.getTableSize(table); - var space = Math.min(size.width, ((this.horizontal || mxUtils.isVml(this.node)) ? - this.bounds.width : this.bounds.height) / this.scale); - - // Opera needs the new width to be scaled - if (mxClient.IS_OP) - { - space *= this.scale; - } - - table.style.width = Math.round(space) + 'px'; - td.style.whiteSpace = 'normal'; - } - else - { - table.style.width = ''; - } - - if (!this.wrap) - { - td.style.whiteSpace = 'nowrap'; - } - else - { - td.style.whiteSpace = 'normal'; - } -}; - -/** - * Function: redrawVml - * - * Updates the VML node(s) to reflect the latest bounds and scale. - */ -mxText.prototype.redrawVml = function() -{ - if (this.node.nodeName == 'g') - { - this.redrawForeignObject(); - } - else if (mxUtils.isVml(this.node)) - { - this.redrawTextbox(); - } - else - { - this.redrawHtmlTable(); - } -}; - -/** - * Function: redrawTextbox - * - * Redraws the textbox for this text. This is only used in IE in exact - * rendering mode. - */ -mxText.prototype.redrawTextbox = function() -{ - // Gets VML textbox - var textbox = this.node; - - // Creates HTML container on the fly - if (textbox.firstChild == null) - { - textbox.appendChild(this.createHtmlTable()); - } - - // Updates the table style and value - var table = textbox.firstChild; - this.updateHtmlTable(table); - this.updateTableWidth(table); - - // Opacity - if (this.opacity != null) - { - mxUtils.setOpacity(table, this.opacity); - } - - table.style.filter = ''; - textbox.inset = '0px,0px,0px,0px'; - - if (this.overflow != 'fill') - { - // Only tables can be used to work out the actual size of the markup - var size = this.getTableSize(table); - var w = size.width * this.scale; - var h = size.height * this.scale; - var offset = this.getOffset(this.bounds.width, this.bounds.height, w, h); - - // Rotates the label (IE only) - if (!this.horizontal) - { - table.style.filter = this.ieVerticalFilter; - } - - // Adds horizontal/vertical spacing - var spacing = this.getSpacing(); - var x = this.bounds.x - offset.x + spacing.x * this.scale; - var y = this.bounds.y - offset.y + spacing.y * this.scale; - - // Textboxes are always relative to their parent shape's top, left corner so - // we use the inset for absolute positioning as they allow negative values - // except for edges where the bounds are used to find the shape center - var x0 = this.bounds.x; - var y0 = this.bounds.y; - var ow = this.bounds.width; - var oh = this.bounds.height; - - // Insets are given as left, top, right, bottom - if (this.horizontal) - { - var tx = Math.round(x - x0); - var ty = Math.round(y - y0); - - var r = Math.min(0, Math.round(x0 + ow - x - w - 1)); - var b = Math.min(0, Math.round(y0 + oh - y - h - 1)); - textbox.inset = tx + 'px,' + ty + 'px,' + r + 'px,' + b + 'px'; - } - else - { - var t = 0; - var l = 0; - var r = 0; - var b = 0; - - if (this.align == mxConstants.ALIGN_CENTER) - { - t = (oh - w) / 2; - b = t; - } - else if (this.align == mxConstants.ALIGN_LEFT) - { - t = oh - w; - } - else - { - b = oh - w; - } - - if (this.valign == mxConstants.ALIGN_MIDDLE) - { - l = (ow - h) / 2; - r = l; - } - else if (this.valign == mxConstants.ALIGN_BOTTOM) - { - l = ow - h; - } - else - { - r = ow - h; - } - - textbox.inset = l + 'px,' + t + 'px,' + r + 'px,' + b + 'px'; - } - - textbox.style.zoom = this.scale; - - // Clipping - if (this.clipped && this.bounds.width > 0 && this.bounds.height > 0) - { - this.boundingBox = this.bounds.clone(); - var dx = Math.round(x0 - x); - var dy = Math.round(y0 - y); - - textbox.style.clip = 'rect(' + (dy / this.scale) + ' ' + - ((dx + this.bounds.width) / this.scale) + ' ' + - ((dy + this.bounds.height) / this.scale) + ' ' + - (dx / this.scale) + ')'; - } - else - { - this.boundingBox = new mxRectangle(x, y, w, h); - } - } - else - { - this.boundingBox = this.bounds.clone(); - } -}; - -/** - * Function: redrawHtmlTable - * - * Redraws the HTML table. This is used for HTML labels in all modes except - * exact in IE and if NO_FO is false for the browser. - */ -mxText.prototype.redrawHtmlTable = function() -{ - if (isNaN(this.bounds.x) || isNaN(this.bounds.y) || - isNaN(this.bounds.width) || isNaN(this.bounds.height)) - { - return; - } - - // Gets table - var table = this.node; - var td = table.firstChild.firstChild.firstChild; - - // Un-rotates for computing the actual size - // TODO: Check if the result can be tweaked instead in getActualSize - // and only do this if actual rotation did change - var oldBrowser = false; - var fallbackScale = 1; - - if (mxClient.IS_IE) - { - table.style.removeAttribute('filter'); - } - else if (mxClient.IS_SF || mxClient.IS_GC) - { - table.style.WebkitTransform = ''; - } - else if (mxClient.IS_MT) - { - table.style.MozTransform = ''; - td.style.MozTransform = ''; - } - else - { - if (mxClient.IS_OT) - { - table.style.OTransform = ''; - } - - fallbackScale = this.scale; - oldBrowser = true; - } - - // Resets the current zoom for text measuring - td.style.zoom = ''; - - // Updates the table style and value - this.updateHtmlTable(table, fallbackScale); - this.updateTableWidth(table); - - // Opacity - if (this.opacity != null) - { - mxUtils.setOpacity(table, this.opacity); - } - - // Resets the bounds for computing the actual size - table.style.left = ''; - table.style.top = ''; - table.style.height = ''; - - // Workaround for multiple zoom even if CSS style is reset here - var currentZoom = parseFloat(td.style.zoom) || 1; - - // Only tables can be used to work out the actual size of the markup - // NOTE: offsetWidth and offsetHeight are very slow in quirks and IE 8 standards mode - var w = this.bounds.width; - var h = this.bounds.height; - - var ignoreStringSize = this.forceIgnoreStringSize || this.overflow == 'fill' || - (this.align == mxConstants.ALIGN_LEFT && this.background == null && this.border == null); - - if (!ignoreStringSize) - { - var size = this.getTableSize(table); - w = size.width / currentZoom; - h = size.height / currentZoom; - } - - var offset = this.getOffset(this.bounds.width / this.scale, - this.bounds.height / this.scale, w, h, - oldBrowser || this.horizontal); - - // Adds horizontal/vertical spacing - var spacing = this.getSpacing(oldBrowser || this.horizontal); - var x = this.bounds.x / this.scale - offset.x + spacing.x; - var y = this.bounds.y / this.scale - offset.y + spacing.y; - - // Updates the table bounds and stores the scale to be used for - // defining the table width and height, as well as an offset - var s = this.scale; - var s2 = 1; - var shiftX = 0; - var shiftY = 0; - - // Rotates the label and adds offset - if (!this.horizontal) - { - if (mxClient.IS_IE && mxClient.IS_SVG) - { - table.style.msTransform = 'rotate(' + this.verticalTextDegree + 'deg)'; - } - else if (mxClient.IS_IE) - { - table.style.filter = this.ieVerticalFilter; - shiftX = (w - h) / 2; - shiftY = -shiftX; - } - else if (mxClient.IS_SF || mxClient.IS_GC) - { - table.style.WebkitTransform = 'rotate(' + this.verticalTextDegree + 'deg)'; - } - else if (mxClient.IS_OT) - { - table.style.OTransform = 'rotate(' + this.verticalTextDegree + 'deg)'; - } - else if (mxClient.IS_MT) - { - // Firefox paints background and border only if background is on TD - // and border is on TABLE and both are rotated, just the TD with a - // rotation of zero (don't remove the 0-rotate CSS style) - table.style.MozTransform = 'rotate(' + this.verticalTextDegree + 'deg)'; - td.style.MozTransform = 'rotate(0deg)'; - - s2 = 1 / this.scale; - s = 1; - } - } - - // Sets the zoom - var correction = true; - - if (mxClient.IS_MT || oldBrowser) - { - if (mxClient.IS_MT) - { - table.style.MozTransform += ' scale(' + this.scale + ')'; - s2 = 1 / this.scale; - } - else if (mxClient.IS_OT) - { - td.style.OTransform = 'scale(' + this.scale + ')'; - table.style.borderWidth = Math.round(this.scale * parseInt(table.style.borderWidth)) + 'px'; - } - } - else if (!oldBrowser) - { - // Workaround for unsupported zoom CSS in IE9 standards mode - if (document.documentMode >= 9) - { - td.style.msTransform = 'scale(' + this.scale + ')'; - } - // Uses transform in Webkit for better HTML scaling - else if (mxClient.IS_SF || mxClient.IS_GC) - { - td.style.WebkitTransform = 'scale(' + this.scale + ')'; - } - else - { - td.style.zoom = this.scale; - - // Fixes scaling of border width - if (table.style.borderWidth != '' && document.documentMode != 8) - { - table.style.borderWidth = Math.round(this.scale * parseInt(table.style.borderWidth)) + 'px'; - } - - // Workaround for wrong scale in IE8 standards mode - if (document.documentMode == 8 || !mxClient.IS_IE) - { - s = 1; - } - - correction = false; - } - } - - if (correction) - { - // Workaround for scaled TD position - shiftX = (this.scale - 1) * w / (2 * this.scale); - shiftY = (this.scale - 1) * h / (2 * this.scale); - s = 1; - } - - if (this.overflow != 'fill') - { - var rect = new mxRectangle(Math.round((x + shiftX) * this.scale), - Math.round((y + shiftY) * this.scale), Math.round(w * s), Math.round(h * s)); - table.style.left = rect.x + 'px'; - table.style.top = rect.y + 'px'; - table.style.width = rect.width + 'px'; - table.style.height = rect.height + 'px'; - - // Workaround for wrong scale in border and background rendering for table and td in IE8/9 standards mode - if ((this.background != null || this.border != null) && document.documentMode >= 8) - { - var html = (this.replaceLinefeeds) ? this.value.replace(/\n/g, '<br/>') : this.value; - td.innerHTML = '<div style="padding:' + this.labelPadding + 'px;background:' + td.style.background + ';border:' + table.style.border + '">' + html + '</div>'; - td.style.padding = '0px'; - td.style.background = ''; - table.style.border = ''; - } - - // Clipping - if (this.clipped && this.bounds.width > 0 && this.bounds.height > 0) - { - this.boundingBox = this.bounds.clone(); - - // Clipping without rotation or for older browsers - if (this.horizontal || (oldBrowser && !mxClient.IS_OT)) - { - var dx = Math.max(0, offset.x * s); - var dy = Math.max(0, offset.y * s); - - // TODO: Fix clipping for Opera - table.style.clip = 'rect(' + (dy) + 'px ' + (dx + this.bounds.width * s2) + - 'px ' + (dy + this.bounds.height * s2) + 'px ' + (dx) + 'px)'; - } - else - { - // Workaround for IE clip using top, right, bottom, left (un-rotated) - if (mxClient.IS_IE) - { - var uw = this.bounds.width; - var uh = this.bounds.height; - var dx = 0; - var dy = 0; - - if (this.align == mxConstants.ALIGN_LEFT) - { - dx = Math.max(0, w - uh / this.scale) * this.scale; - } - else if (this.align == mxConstants.ALIGN_CENTER) - { - dx = Math.max(0, w - uh / this.scale) * this.scale / 2; - } - - if (this.valign == mxConstants.ALIGN_BOTTOM) - { - dy = Math.max(0, h - uw / this.scale) * this.scale; - } - else if (this.valign == mxConstants.ALIGN_MIDDLE) - { - dy = Math.max(0, h - uw / this.scale) * this.scale / 2; - } - - table.style.clip = 'rect(' + (dx) + 'px ' + (dy + uw - 1) + - 'px ' + (dx + uh - 1) + 'px ' + (dy) + 'px)'; - } - else - { - var uw = this.bounds.width / this.scale; - var uh = this.bounds.height / this.scale; - - if (mxClient.IS_OT) - { - uw = this.bounds.width; - uh = this.bounds.height; - } - - var dx = 0; - var dy = 0; - - if (this.align == mxConstants.ALIGN_RIGHT) - { - dx = Math.max(0, w - uh); - } - else if (this.align == mxConstants.ALIGN_CENTER) - { - dx = Math.max(0, w - uh) / 2; - } - - if (this.valign == mxConstants.ALIGN_BOTTOM) - { - dy = Math.max(0, h - uw); - } - else if (this.valign == mxConstants.ALIGN_MIDDLE) - { - dy = Math.max(0, h - uw) / 2; - } - - if (mxClient.IS_GC || mxClient.IS_SF) - { - dx *= this.scale; - dy *= this.scale; - uw *= this.scale; - uh *= this.scale; - } - - table.style.clip = 'rect(' + (dy) + ' ' + (dx + uh) + - ' ' + (dy + uw) + ' ' + (dx) + ')'; - } - } - } - else - { - this.boundingBox = rect; - } - } - else - { - this.boundingBox = this.bounds.clone(); - - if (document.documentMode >= 9 || mxClient.IS_SVG) - { - table.style.left = Math.round(this.bounds.x + this.scale / 2 + shiftX) + 'px'; - table.style.top = Math.round(this.bounds.y + this.scale / 2 + shiftY) + 'px'; - table.style.width = Math.round((this.bounds.width - this.scale) / this.scale) + 'px'; - table.style.height = Math.round((this.bounds.height - this.scale) / this.scale) + 'px'; - } - else - { - s = (document.documentMode == 8) ? this.scale : 1; - table.style.left = Math.round(this.bounds.x + this.scale / 2) + 'px'; - table.style.top = Math.round(this.bounds.y + this.scale / 2) + 'px'; - table.style.width = Math.round((this.bounds.width - this.scale) / s) + 'px'; - table.style.height = Math.round((this.bounds.height - this.scale) / s) + 'px'; - } - } -}; - -/** - * Function: getVerticalOffset - * - * Returns the factors for the offset to be added to the text vertical - * text rotation. This implementation returns (offset.y, -offset.x). - */ -mxText.prototype.getVerticalOffset = function(offset) -{ - return new mxPoint(offset.y, -offset.x); -}; - -/** - * Function: redrawForeignObject - * - * Redraws the foreign object for this text. - */ -mxText.prototype.redrawForeignObject = function() -{ - // Gets SVG group with foreignObject - var group = this.node; - var fo = group.firstChild; - - // Searches the table which appears behind the background - while (fo == this.backgroundNode) - { - fo = fo.nextSibling; - } - - var body = fo.firstChild; - - // Creates HTML container on the fly - if (body.firstChild == null) - { - body.appendChild(this.createHtmlTable()); - } - - // Updates the table style and value - var table = body.firstChild; - this.updateHtmlTable(table); - - // Workaround for bug in Google Chrome where the text is moved to origin if opacity - // is set on the table, so we set the opacity on the foreignObject instead. - if (this.opacity != null) - { - fo.setAttribute('opacity', this.opacity / 100); - } - - // Workaround for table background not appearing above the shape that is - // behind the label in Safari. To solve this, we add a background rect that - // paints the background instead. - if (mxClient.IS_SF) - { - table.style.borderStyle = 'none'; - table.firstChild.firstChild.firstChild.style.background = ''; - - if (this.backgroundNode == null && (this.background != null || this.border != null)) - { - this.backgroundNode = document.createElementNS(mxConstants.NS_SVG, 'rect'); - group.insertBefore(this.backgroundNode, group.firstChild); - } - else if (this.backgroundNode != null && this.background == null && this.border == null) - { - this.backgroundNode.parentNode.removeChild(this.backgroundNode); - this.backgroundNode = null; - } - - if (this.backgroundNode != null) - { - if (this.background != null) - { - this.backgroundNode.setAttribute('fill', this.background); - } - else - { - this.backgroundNode.setAttribute('fill', 'none'); - } - - if (this.border != null) - { - this.backgroundNode.setAttribute('stroke', this.border); - } - else - { - this.backgroundNode.setAttribute('stroke', 'none'); - } - } - } - - var tr = ''; - - if (this.overflow != 'fill') - { - // Resets the bounds for computing the actual size - fo.removeAttribute('width'); - fo.removeAttribute('height'); - fo.style.width = ''; - fo.style.height = ''; - fo.style.clip = ''; - - // Workaround for size of table not updated if inside foreignObject - if (this.wrap || (!mxClient.IS_GC && !mxClient.IS_SF)) - { - document.body.appendChild(table); - } - - this.updateTableWidth(table); - - // Only tables can be used to work out the actual size of the markup - var size = this.getTableSize(table); - var w = size.width; - var h = size.height; - - if (table.parentNode != body) - { - body.appendChild(table); - } - - // Adds horizontal/vertical spacing - var spacing = this.getSpacing(); - - var x = this.bounds.x / this.scale + spacing.x; - var y = this.bounds.y / this.scale + spacing.y; - var uw = this.bounds.width / this.scale; - var uh = this.bounds.height / this.scale; - var offset = this.getOffset(uw, uh, w, h); - - // Rotates the label and adds offset - if (this.horizontal) - { - x -= offset.x; - y -= offset.y; - - tr = 'scale(' + this.scale + ')'; - } - else - { - var x0 = x + w / 2; - var y0 = y + h / 2; - - tr = 'scale(' + this.scale + ') rotate(' + this.verticalTextDegree + ' ' + x0 + ' ' + y0 + ')'; - - var tmp = this.getVerticalOffset(offset); - x += tmp.x; - y += tmp.y; - } - - // Must use translate instead of x- and y-attribute on FO for iOS - tr += ' translate(' + x + ' ' + y + ')'; - - // Updates the bounds of the background node in Webkit - if (this.backgroundNode != null) - { - this.backgroundNode.setAttribute('width', w); - this.backgroundNode.setAttribute('height', h); - } - - // Updates the foreignObject size - fo.setAttribute('width', w); - fo.setAttribute('height', h); - - // Clipping - // TODO: Fix/check clipping for foreignObjects in Chrome 5.0 - if clipPath - // is used in the group then things can no longer be moved around - if (this.clipped && this.bounds.width > 0 && this.bounds.height > 0) - { - this.boundingBox = this.bounds.clone(); - var dx = Math.max(0, offset.x); - var dy = Math.max(0, offset.y); - - if (this.horizontal) - { - fo.style.clip = 'rect(' + dy + 'px,' + (dx + uw) + - 'px,' + (dy + uh) + 'px,' + (dx) + 'px)'; - } - else - { - var dx = 0; - var dy = 0; - - if (this.align == mxConstants.ALIGN_RIGHT) - { - dx = Math.max(0, w - uh); - } - else if (this.align == mxConstants.ALIGN_CENTER) - { - dx = Math.max(0, w - uh) / 2; - } - - if (this.valign == mxConstants.ALIGN_BOTTOM) - { - dy = Math.max(0, h - uw); - } - else if (this.valign == mxConstants.ALIGN_MIDDLE) - { - dy = Math.max(0, h - uw) / 2; - } - - fo.style.clip = 'rect(' + (dy) + 'px,' + (dx + uh) + - 'px,' + (dy + uw) + 'px,' + (dx) + 'px)'; - } - - // Clipping for the background node in Chrome - if (this.backgroundNode != null) - { - x = this.bounds.x / this.scale; - y = this.bounds.y / this.scale; - - if (!this.horizontal) - { - x += (h + w) / 2 - uh; - y += (h - w) / 2; - - var tmp = uw; - uw = uh; - uh = tmp; - } - - // No clipping in Chome available due to bug - if (!mxClient.IS_GC) - { - var clip = this.getSvgClip(this.node.ownerSVGElement, x, y, uw, uh); - - if (clip != this.clip) - { - this.releaseSvgClip(); - this.clip = clip; - clip.refCount++; - } - - this.backgroundNode.setAttribute('clip-path', 'url(#' + clip.getAttribute('id') + ')'); - } - } - } - else - { - // Removes clipping from background and cleans up the clip - this.releaseSvgClip(); - - if (this.backgroundNode != null) - { - this.backgroundNode.removeAttribute('clip-path'); - } - - if (this.horizontal) - { - this.boundingBox = new mxRectangle(x * this.scale, y * this.scale, w * this.scale, h * this.scale); - } - else - { - this.boundingBox = new mxRectangle(x * this.scale, y * this.scale, h * this.scale, w * this.scale); - } - } - } - else - { - this.boundingBox = this.bounds.clone(); - - var s = this.scale; - var w = this.bounds.width / s; - var h = this.bounds.height / s; - - // Updates the foreignObject and table bounds - fo.setAttribute('width', w); - fo.setAttribute('height', h); - table.style.width = w + 'px'; - table.style.height = h + 'px'; - - // Updates the bounds of the background node in Webkit - if (this.backgroundNode != null) - { - this.backgroundNode.setAttribute('width', table.clientWidth); - this.backgroundNode.setAttribute('height', table.offsetHeight); - } - - // Must use translate instead of x- and y-attribute on FO for iOS - tr = 'scale(' + s + ') translate(' + (this.bounds.x / s) + - ' ' + (this.bounds.y / s) + ')'; - - if (!this.wrap) - { - var td = table.firstChild.firstChild.firstChild; - td.style.whiteSpace = 'nowrap'; - } - } - - group.setAttribute('transform', tr); -}; - -/** - * Function: createSvg - * - * Creates and returns the SVG node(s) to represent this shape. - */ -mxText.prototype.createSvg = function() -{ - // Creates a group so that shapes inside are rendered properly, if this is - // a text node then the background rectangle is not rendered in Webkit. - var node = document.createElementNS(mxConstants.NS_SVG, 'g'); - - var uline = this.isStyleSet(mxConstants.FONT_UNDERLINE) ? 'underline' : 'none'; - var weight = this.isStyleSet(mxConstants.FONT_BOLD) ? 'bold' : 'normal'; - var s = this.isStyleSet(mxConstants.FONT_ITALIC) ? 'italic' : null; - - // Underline is not implemented in FF, see - // https://bugzilla.mozilla.org/show_bug.cgi?id=317196 - node.setAttribute('text-decoration', uline); - node.setAttribute('font-family', this.family); - node.setAttribute('font-weight', weight); - node.setAttribute('font-size', Math.round(this.size * this.scale) + 'px'); - node.setAttribute('fill', this.color); - var align = (this.align == mxConstants.ALIGN_RIGHT) ? 'end' : - (this.align == mxConstants.ALIGN_CENTER) ? 'middle' : - 'start'; - node.setAttribute('text-anchor', align); - - if (s != null) - { - node.setAttribute('font-style', s); - } - - // Adds a rectangle for the background color - if (this.background != null || this.border != null) - { - this.backgroundNode = document.createElementNS(mxConstants.NS_SVG, 'rect'); - this.backgroundNode.setAttribute('shape-rendering', 'crispEdges'); - - if (this.background != null) - { - this.backgroundNode.setAttribute('fill', this.background); - } - else - { - this.backgroundNode.setAttribute('fill', 'none'); - } - - if (this.border != null) - { - this.backgroundNode.setAttribute('stroke', this.border); - } - else - { - this.backgroundNode.setAttribute('stroke', 'none'); - } - } - - this.updateSvgValue(node); - - return node; -}; - -/** - * Updates the text represented by the SVG DOM nodes. - */ -mxText.prototype.updateSvgValue = function(node) -{ - if (this.currentValue != this.value) - { - // Removes all existing children - while (node.firstChild != null) - { - node.removeChild(node.firstChild); - } - - if (this.value != null) - { - // Adds tspan elements for the lines - var uline = this.isStyleSet(mxConstants.FONT_UNDERLINE) ? 'underline' : 'none'; - var lines = this.value.split('\n'); - - // Workaround for empty lines breaking the return value of getBBox - // for the enclosing g element so we avoid adding empty lines - // but still count them as a linefeed - this.textNodes = new Array(lines.length); - - for (var i = 0; i < lines.length; i++) - { - if (!this.isEmptyString(lines[i])) - { - var tspan = this.createSvgSpan(lines[i]); - node.appendChild(tspan); - this.textNodes[i] = tspan; - - // Requires either 'inherit' in Webkit or explicit setting - // to work in Webkit and IE9 standards mode. Both, inherit - // and underline do not work in FF. This is a known bug in - // FF (see above). - tspan.setAttribute('text-decoration', uline); - } - else - { - this.textNodes[i] = null; - } - } - } - - this.currentValue = this.value; - } -}; - -/** - * Function: redrawSvg - * - * Updates the SVG node(s) to reflect the latest bounds and scale. - */ -mxText.prototype.redrawSvg = function() -{ - if (this.node.nodeName == 'foreignObject') - { - this.redrawHtml(); - - return; - } - - var fontSize = Math.round(this.size * this.scale); - - if (fontSize <= 0) - { - this.node.setAttribute('visibility', 'hidden'); - } - else - { - this.node.removeAttribute('visibility'); - } - - this.updateSvgValue(this.node); - this.node.setAttribute('font-size', fontSize + 'px'); - - if (this.opacity != null) - { - // Improves opacity performance in Firefox - this.node.setAttribute('fill-opacity', this.opacity/100); - this.node.setAttribute('stroke-opacity', this.opacity/100); - } - - // Workaround to avoid the use of getBBox to find the size - // of the label. A temporary HTML table is created instead. - var previous = this.value; - var table = this.createHtmlTable(); - - // Makes sure the table is updated and replaces all HTML entities - this.lastValue = null; - this.value = mxUtils.htmlEntities(this.value, false); - this.updateHtmlTable(table); - - // Adds the table to the DOM to find the actual size - document.body.appendChild(table); - var w = table.offsetWidth * this.scale; - var h = table.offsetHeight * this.scale; - - // Cleans up the DOM and restores the original value - table.parentNode.removeChild(table); - this.value = previous; - - // Sets the bounding box for the unclipped case so that - // the full background can be painted using it, the initial - // value for dx and the +4 in the width below are for - // error correction of the HTML and SVG text width - var dx = 2 * this.scale; - - if (this.align == mxConstants.ALIGN_CENTER) - { - dx += w / 2; - } - else if (this.align == mxConstants.ALIGN_RIGHT) - { - dx += w; - } - - var dy = Math.round(fontSize * 1.3); - var childCount = this.node.childNodes.length; - var lineCount = (this.textNodes != null) ? this.textNodes.length : 0; - - if (this.backgroundNode != null) - { - childCount--; - } - - var x = this.bounds.x; - var y = this.bounds.y; - - x += (this.align == mxConstants.ALIGN_RIGHT) ? - ((this.horizontal) ? this.bounds.width : this.bounds.height)- - this.spacingRight * this.scale : - (this.align == mxConstants.ALIGN_CENTER) ? - this.spacingLeft * this.scale + - (((this.horizontal) ? this.bounds.width : this.bounds.height) - - this.spacingLeft * this.scale - this.spacingRight * this.scale) / 2 : - this.spacingLeft * this.scale + 1; - - // Makes sure the alignment is like in VML and HTML - y += (this.valign == mxConstants.ALIGN_BOTTOM) ? - ((this.horizontal) ? this.bounds.height : this.bounds.width) - - (lineCount - 1) * dy - this.spacingBottom * this.scale - 4 : - (this.valign == mxConstants.ALIGN_MIDDLE) ? - (this.spacingTop * this.scale + - ((this.horizontal) ? this.bounds.height : this.bounds.width) - - this.spacingBottom * this.scale - - (lineCount - 1.5) * dy) / 2 : - this.spacingTop * this.scale + dy; - - if (this.overflow == 'fill') - { - if (this.align == mxConstants.ALIGN_CENTER) - { - x = Math.max(this.bounds.x + w / 2, x); - } - - y = Math.max(this.bounds.y + fontSize, y); - - this.boundingBox = new mxRectangle(x - dx, y - dy, - w + 4 * this.scale, h + 1 * this.scale); - this.boundingBox.x = Math.min(this.bounds.x, this.boundingBox.x); - this.boundingBox.y = Math.min(this.bounds.y, this.boundingBox.y); - this.boundingBox.width = Math.max(this.bounds.width, this.boundingBox.width); - this.boundingBox.height = Math.max(this.bounds.height, this.boundingBox.height); - } - else - { - this.boundingBox = new mxRectangle(x - dx, y - dy, - w + 4 * this.scale, h + 1 * this.scale); - } - - if (!this.horizontal) - { - var cx = this.bounds.x + this.bounds.width / 2; - var cy = this.bounds.y + this.bounds.height / 2; - - var offsetX = (this.bounds.width - this.bounds.height) / 2; - var offsetY = (this.bounds.height - this.bounds.width) / 2; - - this.node.setAttribute('transform', - 'rotate(' + this.verticalTextDegree + ' ' + cx + ' ' + cy + ') ' + - 'translate(' + (-offsetY) + ' ' + (-offsetX) + ')'); - } - - // TODO: Font-shadow - this.redrawSvgTextNodes(x, y, dy); - - /* - * FIXME: Bounding box is not rotated. This seems to be a problem for - * all vertical text boxes. Workaround is in mxImageExport. - if (!this.horizontal) - { - var b = this.bounds.y + this.bounds.height; - var cx = this.boundingBox.getCenterX() - this.bounds.x; - var cy = this.boundingBox.getCenterY() - this.bounds.y; - - var y = b - cx - this.bounds.height / 2; - this.boundingBox.x = this.bounds.x + cy - this.boundingBox.width / 2; - this.boundingBox.y = y; - } - */ - - // Updates the bounds of the background node if one exists - if (this.value.length > 0 && this.backgroundNode != null && this.node.firstChild != null) - { - if (this.node.firstChild != this.backgroundNode) - { - this.node.insertBefore(this.backgroundNode, this.node.firstChild); - } - - // FIXME: For larger font sizes the linespacing between HTML and SVG - // seems to be different and hence the bounding box isn't accurate. - // Also in Firefox the background box is slighly offset. - this.backgroundNode.setAttribute('x', this.boundingBox.x + this.scale / 2 + 1 * this.scale); - this.backgroundNode.setAttribute('y', this.boundingBox.y + this.scale / 2 + 2 * this.scale - this.labelPadding); - this.backgroundNode.setAttribute('width', this.boundingBox.width - this.scale - 2 * this.scale); - this.backgroundNode.setAttribute('height', this.boundingBox.height - this.scale); - - var strokeWidth = Math.round(Math.max(1, this.scale)); - this.backgroundNode.setAttribute('stroke-width', strokeWidth); - } - - // Adds clipping and updates the bounding box - if (this.clipped && this.bounds.width > 0 && this.bounds.height > 0) - { - this.boundingBox = this.bounds.clone(); - - if (!this.horizontal) - { - this.boundingBox.width = this.bounds.height; - this.boundingBox.height = this.bounds.width; - } - - x = this.bounds.x; - y = this.bounds.y; - - if (this.horizontal) - { - w = this.bounds.width; - h = this.bounds.height; - } - else - { - w = this.bounds.height; - h = this.bounds.width; - } - - var clip = this.getSvgClip(this.node.ownerSVGElement, x, y, w, h); - - if (clip != this.clip) - { - this.releaseSvgClip(); - this.clip = clip; - clip.refCount++; - } - - this.node.setAttribute('clip-path', 'url(#' + clip.getAttribute('id') + ')'); - } - else - { - this.releaseSvgClip(); - this.node.removeAttribute('clip-path'); - } -}; - -/** - * Function: redrawSvgTextNodes - * - * Hook to update the position of the SVG text nodes. - */ -mxText.prototype.redrawSvgTextNodes = function(x, y, dy) -{ - if (this.textNodes != null) - { - var currentY = y; - - for (var i = 0; i < this.textNodes.length; i++) - { - var node = this.textNodes[i]; - - if (node != null) - { - node.setAttribute('x', x); - node.setAttribute('y', currentY); - - // Triggers an update in Firefox 1.5.0.x (don't add a semicolon!) - node.setAttribute('style', 'pointer-events: all'); - } - - currentY += dy; - } - } -}; - -/** - * Function: releaseSvgClip - * - * Releases the given SVG clip removing it from the DOM if required. - */ -mxText.prototype.releaseSvgClip = function() -{ - if (this.clip != null) - { - this.clip.refCount--; - - if (this.clip.refCount == 0) - { - this.clip.parentNode.removeChild(this.clip); - } - - this.clip = null; - } -}; - -/** - * Function: getSvgClip - * - * Returns a new or existing SVG clip path which is a descendant of the given - * SVG node with a unique ID. - */ -mxText.prototype.getSvgClip = function(svg, x, y, w, h) -{ - x = Math.round(x); - y = Math.round(y); - w = Math.round(w); - h = Math.round(h); - - var id = 'mx-clip-' + x + '-' + y + '-' + w + '-' + h; - - // Quick access - if (this.clip != null && this.clip.ident == id) - { - return this.clip; - } - - var counter = 0; - var tmp = id + '-' + counter; - var clip = document.getElementById(tmp); - - // Tries to find an existing clip in the given SVG - while (clip != null) - { - if (clip.ownerSVGElement == svg) - { - return clip; - } - - counter++; - tmp = id + '-' + counter; - clip = document.getElementById(tmp); - } - - // Creates a new clip node and adds it to the DOM - if (clip != null) - { - clip = clip.cloneNode(true); - counter++; - } - else - { - clip = document.createElementNS(mxConstants.NS_SVG, 'clipPath'); - - var rect = document.createElementNS(mxConstants.NS_SVG, 'rect'); - rect.setAttribute('x', x); - rect.setAttribute('y', y); - rect.setAttribute('width', w); - rect.setAttribute('height', h); - - clip.appendChild(rect); - } - - clip.setAttribute('id', id + '-' + counter); - clip.ident = id; // For quick access above - svg.appendChild(clip); - clip.refCount = 0; - - return clip; -}; - -/** - * Function: isEmptyString - * - * Returns true if the given string is empty or - * contains only whitespace. - */ -mxText.prototype.isEmptyString = function(text) -{ - return text.replace(/ /g, '').length == 0; -}; - -/** - * Function: createSvgSpan - * - * Creats an SVG tspan node for the given text. - */ -mxText.prototype.createSvgSpan = function(text) -{ - // Creates a text node since there is no enclosing text element but - // rather a group, which is required to render the background rectangle - // in Webkit. This can be changed to tspan if the enclosing node is - // a text but this leads to an hidden background in Webkit. - var node = document.createElementNS(mxConstants.NS_SVG, 'text'); - // Needed to preserve multiple white spaces, but ignored in IE9 plus white-space:pre - // is ignored in HTML output for VML, so better to not use this for SVG labels - // node.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve') - // Alternative idea is to replace all spaces with to fix HTML in IE, but - // IE9/10 with SVG will still ignore the xml:space preserve tag as discussed here: - // http://stackoverflow.com/questions/8086292/significant-whitespace-in-svg-embedded-in-html - // Could replace spaces with in text but HTML tags must be scaped first. - mxUtils.write(node, text); - - return node; -}; - -/** - * Function: destroy - * - * Extends destroy to remove any allocated SVG clips. - */ -mxText.prototype.destroy = function() -{ - this.releaseSvgClip(); - mxShape.prototype.destroy.apply(this, arguments); -}; diff --git a/src/js/shape/mxTriangle.js b/src/js/shape/mxTriangle.js deleted file mode 100644 index 3a48db2..0000000 --- a/src/js/shape/mxTriangle.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * $Id: mxTriangle.js,v 1.10 2011-09-02 10:01:00 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxTriangle - * - * Implementation of the triangle shape. - * - * Constructor: mxTriangle - * - * Constructs a new triangle shape. - */ -function mxTriangle() { }; - -/** - * Extends <mxActor>. - */ -mxTriangle.prototype = new mxActor(); -mxTriangle.prototype.constructor = mxTriangle; - -/** - * Function: redrawPath - * - * Draws the path for this shape. This method uses the <mxPath> - * abstraction to paint the shape for VML and SVG. - */ -mxTriangle.prototype.redrawPath = function(path, x, y, w, h) -{ - path.moveTo(0, 0); - path.lineTo(w, 0.5 * h); - path.lineTo(0, h); - path.close(); -}; |