summaryrefslogtreecommitdiff
path: root/src/js/shape/mxText.js
diff options
context:
space:
mode:
authoradhitya2016-04-10 12:28:28 +0000
committeradhitya2016-04-10 12:28:28 +0000
commit0b1c069f88dab0288a01c6aed4d77f4e6d2f6474 (patch)
treeb5ae6b1f512a674f79674a12f675d22324cd268f /src/js/shape/mxText.js
parent1993f1da86e293aaf9996b8d7a4f6d9a9224f270 (diff)
downloadxcos-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/mxText.js')
-rw-r--r--src/js/shape/mxText.js1811
1 files changed, 0 insertions, 1811 deletions
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 &nbsp; 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 &nbsp; 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);
-};