From dd83478e3fcaac98de690aa59e6288ad41a1c351 Mon Sep 17 00:00:00 2001 From: adhitya Date: Tue, 12 Apr 2016 07:02:39 +0000 Subject: Keyboard shortcuts work properly --- src/css/common.css | 152 - src/css/explorer.css | 15 - src/images/button.gif | Bin 137 -> 0 bytes src/images/close.gif | Bin 70 -> 0 bytes src/images/collapsed.gif | Bin 877 -> 0 bytes src/images/error.gif | Bin 907 -> 0 bytes src/images/expanded.gif | Bin 878 -> 0 bytes src/images/maximize.gif | Bin 843 -> 0 bytes src/images/minimize.gif | Bin 64 -> 0 bytes src/images/normalize.gif | Bin 845 -> 0 bytes src/images/point.gif | Bin 55 -> 0 bytes src/images/resize.gif | Bin 74 -> 0 bytes src/images/separator.gif | Bin 146 -> 0 bytes src/images/submenu.gif | Bin 56 -> 0 bytes src/images/transparent.gif | Bin 90 -> 0 bytes src/images/warning.gif | Bin 276 -> 0 bytes src/images/warning.png | Bin 425 -> 0 bytes src/images/window-title.gif | Bin 275 -> 0 bytes src/images/window.gif | Bin 75 -> 0 bytes src/js/editor/mxDefaultKeyHandler.js | 126 - src/js/editor/mxDefaultPopupMenu.js | 300 - src/js/editor/mxDefaultToolbar.js | 567 - src/js/editor/mxEditor.js | 3220 ------ src/js/handler/mxCellHighlight.js | 271 - src/js/handler/mxCellMarker.js | 419 - src/js/handler/mxCellTracker.js | 149 - src/js/handler/mxConnectionHandler.js | 1969 ---- src/js/handler/mxConstraintHandler.js | 308 - src/js/handler/mxEdgeHandler.js | 1529 --- src/js/handler/mxEdgeSegmentHandler.js | 284 - src/js/handler/mxElbowEdgeHandler.js | 248 - src/js/handler/mxGraphHandler.js | 916 -- src/js/handler/mxKeyHandler.js | 402 - src/js/handler/mxPanningHandler.js | 390 - src/js/handler/mxRubberband.js | 348 - src/js/handler/mxSelectionCellsHandler.js | 260 - src/js/handler/mxTooltipHandler.js | 317 - src/js/handler/mxVertexHandler.js | 753 -- src/js/index.txt | 316 - src/js/io/mxCellCodec.js | 170 - src/js/io/mxChildChangeCodec.js | 149 - src/js/io/mxCodec.js | 531 - src/js/io/mxCodecRegistry.js | 137 - src/js/io/mxDefaultKeyHandlerCodec.js | 88 - src/js/io/mxDefaultPopupMenuCodec.js | 54 - src/js/io/mxDefaultToolbarCodec.js | 301 - src/js/io/mxEditorCodec.js | 246 - src/js/io/mxGenericChangeCodec.js | 64 - src/js/io/mxGraphCodec.js | 28 - src/js/io/mxGraphViewCodec.js | 197 - src/js/io/mxModelCodec.js | 80 - src/js/io/mxObjectCodec.js | 983 -- src/js/io/mxRootChangeCodec.js | 83 - src/js/io/mxStylesheetCodec.js | 210 - src/js/io/mxTerminalChangeCodec.js | 42 - .../model/mxGraphAbstractHierarchyCell.js | 206 - .../hierarchical/model/mxGraphHierarchyEdge.js | 174 - .../hierarchical/model/mxGraphHierarchyModel.js | 685 -- .../hierarchical/model/mxGraphHierarchyNode.js | 210 - src/js/layout/hierarchical/mxHierarchicalLayout.js | 623 -- .../hierarchical/stage/mxCoordinateAssignment.js | 1836 --- .../stage/mxHierarchicalLayoutStage.js | 25 - .../stage/mxMedianHybridCrossingReduction.js | 674 -- .../hierarchical/stage/mxMinimumCycleRemover.js | 131 - src/js/layout/mxCircleLayout.js | 203 - src/js/layout/mxCompactTreeLayout.js | 995 -- src/js/layout/mxCompositeLayout.js | 101 - src/js/layout/mxEdgeLabelLayout.js | 165 - src/js/layout/mxFastOrganicLayout.js | 591 - src/js/layout/mxGraphLayout.js | 503 - src/js/layout/mxParallelEdgeLayout.js | 198 - src/js/layout/mxPartitionLayout.js | 240 - src/js/layout/mxStackLayout.js | 381 - src/js/model/mxCell.js | 806 -- src/js/model/mxCellPath.js | 163 - src/js/model/mxGeometry.js | 277 - src/js/model/mxGraphModel.js | 2622 ----- src/js/mxClient.js | 643 -- src/js/shape/mxActor.js | 183 - src/js/shape/mxArrow.js | 226 - src/js/shape/mxCloud.js | 56 - src/js/shape/mxConnector.js | 446 - src/js/shape/mxCylinder.js | 319 - src/js/shape/mxDoubleEllipse.js | 203 - src/js/shape/mxEllipse.js | 132 - src/js/shape/mxHexagon.js | 37 - src/js/shape/mxImageShape.js | 405 - src/js/shape/mxLabel.js | 427 - src/js/shape/mxLine.js | 217 - src/js/shape/mxMarker.js | 267 - src/js/shape/mxPolyline.js | 146 - src/js/shape/mxRectangleShape.js | 61 - src/js/shape/mxRhombus.js | 172 - src/js/shape/mxShape.js | 2045 ---- src/js/shape/mxStencil.js | 1585 --- src/js/shape/mxStencilRegistry.js | 53 - src/js/shape/mxStencilShape.js | 209 - src/js/shape/mxSwimlane.js | 553 - src/js/shape/mxText.js | 1811 --- src/js/shape/mxTriangle.js | 34 - src/js/util/mxAnimation.js | 82 - src/js/util/mxAutoSaveManager.js | 213 - src/js/util/mxClipboard.js | 144 - src/js/util/mxConstants.js | 1911 ---- src/js/util/mxDictionary.js | 130 - src/js/util/mxDivResizer.js | 151 - src/js/util/mxDragSource.js | 594 - src/js/util/mxEffects.js | 214 - src/js/util/mxEvent.js | 1175 -- src/js/util/mxEventObject.js | 111 - src/js/util/mxEventSource.js | 191 - src/js/util/mxForm.js | 202 - src/js/util/mxGuide.js | 364 - src/js/util/mxImage.js | 40 - src/js/util/mxImageBundle.js | 98 - src/js/util/mxImageExport.js | 1412 --- src/js/util/mxLog.js | 410 - src/js/util/mxMorphing.js | 239 - src/js/util/mxMouseEvent.js | 241 - src/js/util/mxObjectIdentity.js | 59 - src/js/util/mxPanningManager.js | 262 - src/js/util/mxPath.js | 314 - src/js/util/mxPoint.js | 55 - src/js/util/mxPopupMenu.js | 574 - src/js/util/mxRectangle.js | 134 - src/js/util/mxResources.js | 366 - src/js/util/mxSession.js | 674 -- src/js/util/mxSvgCanvas2D.js | 1234 -- src/js/util/mxToolbar.js | 528 - src/js/util/mxUndoManager.js | 229 - src/js/util/mxUndoableEdit.js | 168 - src/js/util/mxUrlConverter.js | 141 - src/js/util/mxUtils.js | 3920 ------- src/js/util/mxWindow.js | 1065 -- src/js/util/mxXmlCanvas2D.js | 715 -- src/js/util/mxXmlRequest.js | 425 - src/js/view/mxCellEditor.js | 522 - src/js/view/mxCellOverlay.js | 233 - src/js/view/mxCellRenderer.js | 1480 --- src/js/view/mxCellState.js | 375 - src/js/view/mxCellStatePreview.js | 223 - src/js/view/mxConnectionConstraint.js | 42 - src/js/view/mxEdgeStyle.js | 1302 --- src/js/view/mxGraph.js | 11176 ------------------- src/js/view/mxGraphSelectionModel.js | 435 - src/js/view/mxGraphView.js | 2545 ----- src/js/view/mxLayoutManager.js | 375 - src/js/view/mxMultiplicity.js | 257 - src/js/view/mxOutline.js | 649 -- src/js/view/mxPerimeter.js | 484 - src/js/view/mxPrintPreview.js | 801 -- src/js/view/mxSpaceManager.js | 460 - src/js/view/mxStyleRegistry.js | 70 - src/js/view/mxStylesheet.js | 266 - src/js/view/mxSwimlaneManager.js | 449 - src/js/view/mxTemporaryCellStates.js | 105 - src/js/xcos/core/details.js | 204 - src/resources/editor.properties | 5 - src/resources/graph.properties | 11 - 159 files changed, 79915 deletions(-) delete mode 100644 src/css/common.css delete mode 100644 src/css/explorer.css delete mode 100644 src/images/button.gif delete mode 100644 src/images/close.gif delete mode 100644 src/images/collapsed.gif delete mode 100644 src/images/error.gif delete mode 100644 src/images/expanded.gif delete mode 100644 src/images/maximize.gif delete mode 100644 src/images/minimize.gif delete mode 100644 src/images/normalize.gif delete mode 100644 src/images/point.gif delete mode 100644 src/images/resize.gif delete mode 100644 src/images/separator.gif delete mode 100644 src/images/submenu.gif delete mode 100644 src/images/transparent.gif delete mode 100644 src/images/warning.gif delete mode 100644 src/images/warning.png delete mode 100644 src/images/window-title.gif delete mode 100644 src/images/window.gif delete mode 100644 src/js/editor/mxDefaultKeyHandler.js delete mode 100644 src/js/editor/mxDefaultPopupMenu.js delete mode 100644 src/js/editor/mxDefaultToolbar.js delete mode 100644 src/js/editor/mxEditor.js delete mode 100644 src/js/handler/mxCellHighlight.js delete mode 100644 src/js/handler/mxCellMarker.js delete mode 100644 src/js/handler/mxCellTracker.js delete mode 100644 src/js/handler/mxConnectionHandler.js delete mode 100644 src/js/handler/mxConstraintHandler.js delete mode 100644 src/js/handler/mxEdgeHandler.js delete mode 100644 src/js/handler/mxEdgeSegmentHandler.js delete mode 100644 src/js/handler/mxElbowEdgeHandler.js delete mode 100644 src/js/handler/mxGraphHandler.js delete mode 100644 src/js/handler/mxKeyHandler.js delete mode 100644 src/js/handler/mxPanningHandler.js delete mode 100644 src/js/handler/mxRubberband.js delete mode 100644 src/js/handler/mxSelectionCellsHandler.js delete mode 100644 src/js/handler/mxTooltipHandler.js delete mode 100644 src/js/handler/mxVertexHandler.js delete mode 100644 src/js/index.txt delete mode 100644 src/js/io/mxCellCodec.js delete mode 100644 src/js/io/mxChildChangeCodec.js delete mode 100644 src/js/io/mxCodec.js delete mode 100644 src/js/io/mxCodecRegistry.js delete mode 100644 src/js/io/mxDefaultKeyHandlerCodec.js delete mode 100644 src/js/io/mxDefaultPopupMenuCodec.js delete mode 100644 src/js/io/mxDefaultToolbarCodec.js delete mode 100644 src/js/io/mxEditorCodec.js delete mode 100644 src/js/io/mxGenericChangeCodec.js delete mode 100644 src/js/io/mxGraphCodec.js delete mode 100644 src/js/io/mxGraphViewCodec.js delete mode 100644 src/js/io/mxModelCodec.js delete mode 100644 src/js/io/mxObjectCodec.js delete mode 100644 src/js/io/mxRootChangeCodec.js delete mode 100644 src/js/io/mxStylesheetCodec.js delete mode 100644 src/js/io/mxTerminalChangeCodec.js delete mode 100644 src/js/layout/hierarchical/model/mxGraphAbstractHierarchyCell.js delete mode 100644 src/js/layout/hierarchical/model/mxGraphHierarchyEdge.js delete mode 100644 src/js/layout/hierarchical/model/mxGraphHierarchyModel.js delete mode 100644 src/js/layout/hierarchical/model/mxGraphHierarchyNode.js delete mode 100644 src/js/layout/hierarchical/mxHierarchicalLayout.js delete mode 100644 src/js/layout/hierarchical/stage/mxCoordinateAssignment.js delete mode 100644 src/js/layout/hierarchical/stage/mxHierarchicalLayoutStage.js delete mode 100644 src/js/layout/hierarchical/stage/mxMedianHybridCrossingReduction.js delete mode 100644 src/js/layout/hierarchical/stage/mxMinimumCycleRemover.js delete mode 100644 src/js/layout/mxCircleLayout.js delete mode 100644 src/js/layout/mxCompactTreeLayout.js delete mode 100644 src/js/layout/mxCompositeLayout.js delete mode 100644 src/js/layout/mxEdgeLabelLayout.js delete mode 100644 src/js/layout/mxFastOrganicLayout.js delete mode 100644 src/js/layout/mxGraphLayout.js delete mode 100644 src/js/layout/mxParallelEdgeLayout.js delete mode 100644 src/js/layout/mxPartitionLayout.js delete mode 100644 src/js/layout/mxStackLayout.js delete mode 100644 src/js/model/mxCell.js delete mode 100644 src/js/model/mxCellPath.js delete mode 100644 src/js/model/mxGeometry.js delete mode 100644 src/js/model/mxGraphModel.js delete mode 100644 src/js/mxClient.js delete mode 100644 src/js/shape/mxActor.js delete mode 100644 src/js/shape/mxArrow.js delete mode 100644 src/js/shape/mxCloud.js delete mode 100644 src/js/shape/mxConnector.js delete mode 100644 src/js/shape/mxCylinder.js delete mode 100644 src/js/shape/mxDoubleEllipse.js delete mode 100644 src/js/shape/mxEllipse.js delete mode 100644 src/js/shape/mxHexagon.js delete mode 100644 src/js/shape/mxImageShape.js delete mode 100644 src/js/shape/mxLabel.js delete mode 100644 src/js/shape/mxLine.js delete mode 100644 src/js/shape/mxMarker.js delete mode 100644 src/js/shape/mxPolyline.js delete mode 100644 src/js/shape/mxRectangleShape.js delete mode 100644 src/js/shape/mxRhombus.js delete mode 100644 src/js/shape/mxShape.js delete mode 100644 src/js/shape/mxStencil.js delete mode 100644 src/js/shape/mxStencilRegistry.js delete mode 100644 src/js/shape/mxStencilShape.js delete mode 100644 src/js/shape/mxSwimlane.js delete mode 100644 src/js/shape/mxText.js delete mode 100644 src/js/shape/mxTriangle.js delete mode 100644 src/js/util/mxAnimation.js delete mode 100644 src/js/util/mxAutoSaveManager.js delete mode 100644 src/js/util/mxClipboard.js delete mode 100644 src/js/util/mxConstants.js delete mode 100644 src/js/util/mxDictionary.js delete mode 100644 src/js/util/mxDivResizer.js delete mode 100644 src/js/util/mxDragSource.js delete mode 100644 src/js/util/mxEffects.js delete mode 100644 src/js/util/mxEvent.js delete mode 100644 src/js/util/mxEventObject.js delete mode 100644 src/js/util/mxEventSource.js delete mode 100644 src/js/util/mxForm.js delete mode 100644 src/js/util/mxGuide.js delete mode 100644 src/js/util/mxImage.js delete mode 100644 src/js/util/mxImageBundle.js delete mode 100644 src/js/util/mxImageExport.js delete mode 100644 src/js/util/mxLog.js delete mode 100644 src/js/util/mxMorphing.js delete mode 100644 src/js/util/mxMouseEvent.js delete mode 100644 src/js/util/mxObjectIdentity.js delete mode 100644 src/js/util/mxPanningManager.js delete mode 100644 src/js/util/mxPath.js delete mode 100644 src/js/util/mxPoint.js delete mode 100644 src/js/util/mxPopupMenu.js delete mode 100644 src/js/util/mxRectangle.js delete mode 100644 src/js/util/mxResources.js delete mode 100644 src/js/util/mxSession.js delete mode 100644 src/js/util/mxSvgCanvas2D.js delete mode 100644 src/js/util/mxToolbar.js delete mode 100644 src/js/util/mxUndoManager.js delete mode 100644 src/js/util/mxUndoableEdit.js delete mode 100644 src/js/util/mxUrlConverter.js delete mode 100644 src/js/util/mxUtils.js delete mode 100644 src/js/util/mxWindow.js delete mode 100644 src/js/util/mxXmlCanvas2D.js delete mode 100644 src/js/util/mxXmlRequest.js delete mode 100644 src/js/view/mxCellEditor.js delete mode 100644 src/js/view/mxCellOverlay.js delete mode 100644 src/js/view/mxCellRenderer.js delete mode 100644 src/js/view/mxCellState.js delete mode 100644 src/js/view/mxCellStatePreview.js delete mode 100644 src/js/view/mxConnectionConstraint.js delete mode 100644 src/js/view/mxEdgeStyle.js delete mode 100644 src/js/view/mxGraph.js delete mode 100644 src/js/view/mxGraphSelectionModel.js delete mode 100644 src/js/view/mxGraphView.js delete mode 100644 src/js/view/mxLayoutManager.js delete mode 100644 src/js/view/mxMultiplicity.js delete mode 100644 src/js/view/mxOutline.js delete mode 100644 src/js/view/mxPerimeter.js delete mode 100644 src/js/view/mxPrintPreview.js delete mode 100644 src/js/view/mxSpaceManager.js delete mode 100644 src/js/view/mxStyleRegistry.js delete mode 100644 src/js/view/mxStylesheet.js delete mode 100644 src/js/view/mxSwimlaneManager.js delete mode 100644 src/js/view/mxTemporaryCellStates.js delete mode 100644 src/js/xcos/core/details.js delete mode 100644 src/resources/editor.properties delete mode 100644 src/resources/graph.properties (limited to 'src') diff --git a/src/css/common.css b/src/css/common.css deleted file mode 100644 index 5eb0b45..0000000 --- a/src/css/common.css +++ /dev/null @@ -1,152 +0,0 @@ -div.mxRubberband { - position: absolute; - overflow: hidden; - border-style: solid; - border-width: 1px; - border-color: #0000FF; - background: #0077FF; -} -textarea.mxCellEditor { - background: url('../images/transparent.gif'); - border-style: solid; - border-color: black; - border-width: 0; - overflow: auto; -} -div.mxWindow { - -webkit-box-shadow: 3px 3px 12px #C0C0C0; - -moz-box-shadow: 3px 3px 12px #C0C0C0; - box-shadow: 3px 3px 12px #C0C0C0; - background: url('../images/window.gif'); - border-style: outset; - border-width: 1px; - position: absolute; - overflow: hidden; - z-index: 1; -} -table.mxWindow { - border-collapse: collapse; - table-layout: fixed; - font-family: Arial; - font-size: 8pt; -} -td.mxWindowTitle { - background: url('../images/window-title.gif') repeat-x; - text-overflow: ellipsis; - white-space: nowrap; - text-align: center; - font-weight: bold; - overflow: hidden; - height: 13px; - padding: 2px; - padding-top: 4px; - padding-bottom: 6px; - color: black; -} -td.mxWindowPane { - vertical-align: top; - padding: 0px; -} -div.mxWindowPane { - overflow: hidden; -} -td.mxWindowPane td { - font-family: Arial; - font-size: 8pt; -} -td.mxWindowPane input, td.mxWindowPane select, td.mxWindowPane textarea, td.mxWindowPane radio { - border-color: #8C8C8C; - border-style: solid; - border-width: 1px; - font-family: Arial; - font-size: 8pt; - padding: 1px; -} -td.mxWindowPane button { - background: url('../images/button.gif') repeat-x; - font-family: Arial; - font-size: 8pt; - padding: 2px; - float: left; -} -img.mxToolbarItem { - margin-right: 6px; - margin-bottom: 6px; - border-width: 1px; -} -select.mxToolbarCombo { - vertical-align: top; - border-style: inset; - border-width: 2px; -} -div.mxToolbarComboContainer { - padding: 2px; -} -img.mxToolbarMode { - margin: 2px; - margin-right: 4px; - margin-bottom: 4px; - border-width: 0px; -} -img.mxToolbarModeSelected { - margin: 0px; - margin-right: 2px; - margin-bottom: 2px; - border-width: 2px; - border-style: inset; -} -div.mxTooltip { - -webkit-box-shadow: 3px 3px 12px #C0C0C0; - -moz-box-shadow: 3px 3px 12px #C0C0C0; - box-shadow: 3px 3px 12px #C0C0C0; - background: #FFFFCC; - border-style: solid; - border-width: 1px; - border-color: black; - font-family: Arial; - font-size: 8pt; - position: absolute; - cursor: default; - padding: 4px; - color: black; -} -div.mxPopupMenu { - -webkit-box-shadow: 3px 3px 12px #C0C0C0; - -moz-box-shadow: 3px 3px 12px #C0C0C0; - box-shadow: 3px 3px 12px #C0C0C0; - background: url('../images/window.gif'); - position: absolute; - border-style: solid; - border-width: 1px; - border-color: black; - cursor: default; -} -table.mxPopupMenu { - border-collapse: collapse; - margin-top: 1px; - margin-bottom: 1px; -} -tr.mxPopupMenuItem { - color: black; - cursor: default; -} -td.mxPopupMenuItem.disabled { - opacity: 0.2; -} -td.mxPopupMenuItem.disabled { - _filter:alpha(opacity=20) !important; -} -tr.mxPopupMenuItemHover { - background-color: #000066; - color: #FFFFFF; -} -td.mxPopupMenuItem { - padding: 2px 30px 2px 10px; - white-space: nowrap; - font-family: Arial; - font-size: 8pt; -} -td.mxPopupMenuIcon { - background-color: #D0D0D0; - padding: 2px 4px 2px 4px; -} diff --git a/src/css/explorer.css b/src/css/explorer.css deleted file mode 100644 index dfbbd21..0000000 --- a/src/css/explorer.css +++ /dev/null @@ -1,15 +0,0 @@ -div.mxTooltip { - filter:progid:DXImageTransform.Microsoft.DropShadow(OffX=4, OffY=4, - Color='#A2A2A2', Positive='true') -} -div.mxPopupMenu { - filter:progid:DXImageTransform.Microsoft.DropShadow(OffX=4, OffY=4, - Color='#C0C0C0', Positive='true') -} -div.mxWindow { - filter:progid:DXImageTransform.Microsoft.DropShadow(OffX=4, OffY=4, - Color='#C0C0C0', Positive='true') -} -td.mxWindowTitle { - _height: 23px; -} diff --git a/src/images/button.gif b/src/images/button.gif deleted file mode 100644 index ad55cab..0000000 Binary files a/src/images/button.gif and /dev/null differ diff --git a/src/images/close.gif b/src/images/close.gif deleted file mode 100644 index 1069e94..0000000 Binary files a/src/images/close.gif and /dev/null differ diff --git a/src/images/collapsed.gif b/src/images/collapsed.gif deleted file mode 100644 index 0276444..0000000 Binary files a/src/images/collapsed.gif and /dev/null differ diff --git a/src/images/error.gif b/src/images/error.gif deleted file mode 100644 index 14e1aee..0000000 Binary files a/src/images/error.gif and /dev/null differ diff --git a/src/images/expanded.gif b/src/images/expanded.gif deleted file mode 100644 index 3767b0b..0000000 Binary files a/src/images/expanded.gif and /dev/null differ diff --git a/src/images/maximize.gif b/src/images/maximize.gif deleted file mode 100644 index e27cf3e..0000000 Binary files a/src/images/maximize.gif and /dev/null differ diff --git a/src/images/minimize.gif b/src/images/minimize.gif deleted file mode 100644 index 1e95e7c..0000000 Binary files a/src/images/minimize.gif and /dev/null differ diff --git a/src/images/normalize.gif b/src/images/normalize.gif deleted file mode 100644 index 34a8d30..0000000 Binary files a/src/images/normalize.gif and /dev/null differ diff --git a/src/images/point.gif b/src/images/point.gif deleted file mode 100644 index 9074c39..0000000 Binary files a/src/images/point.gif and /dev/null differ diff --git a/src/images/resize.gif b/src/images/resize.gif deleted file mode 100644 index ff558db..0000000 Binary files a/src/images/resize.gif and /dev/null differ diff --git a/src/images/separator.gif b/src/images/separator.gif deleted file mode 100644 index 5c1b895..0000000 Binary files a/src/images/separator.gif and /dev/null differ diff --git a/src/images/submenu.gif b/src/images/submenu.gif deleted file mode 100644 index ffe7617..0000000 Binary files a/src/images/submenu.gif and /dev/null differ diff --git a/src/images/transparent.gif b/src/images/transparent.gif deleted file mode 100644 index 76040f2..0000000 Binary files a/src/images/transparent.gif and /dev/null differ diff --git a/src/images/warning.gif b/src/images/warning.gif deleted file mode 100644 index 705235f..0000000 Binary files a/src/images/warning.gif and /dev/null differ diff --git a/src/images/warning.png b/src/images/warning.png deleted file mode 100644 index 2f78789..0000000 Binary files a/src/images/warning.png and /dev/null differ diff --git a/src/images/window-title.gif b/src/images/window-title.gif deleted file mode 100644 index 231def8..0000000 Binary files a/src/images/window-title.gif and /dev/null differ diff --git a/src/images/window.gif b/src/images/window.gif deleted file mode 100644 index 6631c4f..0000000 Binary files a/src/images/window.gif and /dev/null differ diff --git a/src/js/editor/mxDefaultKeyHandler.js b/src/js/editor/mxDefaultKeyHandler.js deleted file mode 100644 index 3814e5e..0000000 --- a/src/js/editor/mxDefaultKeyHandler.js +++ /dev/null @@ -1,126 +0,0 @@ -/** - * $Id: mxDefaultKeyHandler.js,v 1.26 2010-01-02 09:45:15 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxDefaultKeyHandler - * - * Binds keycodes to actionnames in an editor. This aggregates an internal - * and extends the implementation of to not - * only cancel the editing, but also hide the properties dialog and fire an - * event via . An instance of this class is created - * by and stored in . - * - * Example: - * - * Bind the delete key to the delete action in an existing editor. - * - * (code) - * var keyHandler = new mxDefaultKeyHandler(editor); - * keyHandler.bindAction(46, 'delete'); - * (end) - * - * Codec: - * - * This class uses the to read configuration - * data into an existing instance. See for a - * description of the configuration format. - * - * Keycodes: - * - * See . - * - * An event is fired via the editor if the escape key is - * pressed. - * - * Constructor: mxDefaultKeyHandler - * - * Constructs a new default key handler for the in the - * given . (The editor may be null if a prototypical instance for - * a is created.) - * - * Parameters: - * - * editor - Reference to the enclosing . - */ -function mxDefaultKeyHandler(editor) -{ - if (editor != null) - { - this.editor = editor; - this.handler = new mxKeyHandler(editor.graph); - - // Extends the escape function of the internal key - // handle to hide the properties dialog and fire - // the escape event via the editor instance - var old = this.handler.escape; - - this.handler.escape = function(evt) - { - old.apply(this, arguments); - editor.hideProperties(); - editor.fireEvent(new mxEventObject(mxEvent.ESCAPE, 'event', evt)); - }; - } -}; - -/** - * Variable: editor - * - * Reference to the enclosing . - */ -mxDefaultKeyHandler.prototype.editor = null; - -/** - * Variable: handler - * - * Holds the for key event handling. - */ -mxDefaultKeyHandler.prototype.handler = null; - -/** - * Function: bindAction - * - * Binds the specified keycode to the given action in . The - * optional control flag specifies if the control key must be pressed - * to trigger the action. - * - * Parameters: - * - * code - Integer that specifies the keycode. - * action - Name of the action to execute in . - * control - Optional boolean that specifies if control must be pressed. - * Default is false. - */ -mxDefaultKeyHandler.prototype.bindAction = function (code, action, control) -{ - var keyHandler = mxUtils.bind(this, function() - { - this.editor.execute(action); - }); - - // Binds the function to control-down keycode - if (control) - { - this.handler.bindControlKey(code, keyHandler); - } - - // Binds the function to the normal keycode - else - { - this.handler.bindKey(code, keyHandler); - } -}; - -/** - * Function: destroy - * - * Destroys the associated with this object. This does normally - * not need to be called, the is destroyed automatically when the - * window unloads (in IE) by . - */ -mxDefaultKeyHandler.prototype.destroy = function () -{ - this.handler.destroy(); - this.handler = null; -}; diff --git a/src/js/editor/mxDefaultPopupMenu.js b/src/js/editor/mxDefaultPopupMenu.js deleted file mode 100644 index 01c65b5..0000000 --- a/src/js/editor/mxDefaultPopupMenu.js +++ /dev/null @@ -1,300 +0,0 @@ -/** - * $Id: mxDefaultPopupMenu.js,v 1.29 2012-07-03 06:30:25 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxDefaultPopupMenu - * - * Creates popupmenus for mouse events. This object holds an XML node - * which is a description of the popup menu to be created. In - * , the configuration is applied to the context and - * the resulting menu items are added to the menu dynamically. See - * for a description of the configuration format. - * - * This class does not create the DOM nodes required for the popup menu, it - * only parses an XML description to invoke the respective methods on an - * each time the menu is displayed. - * - * Codec: - * - * This class uses the to read configuration - * data into an existing instance, however, the actual parsing is done - * by this class during program execution, so the format is described - * below. - * - * Constructor: mxDefaultPopupMenu - * - * Constructs a new popupmenu-factory based on given configuration. - * - * Paramaters: - * - * config - XML node that contains the configuration data. - */ -function mxDefaultPopupMenu(config) -{ - this.config = config; -}; - -/** - * Variable: imageBasePath - * - * Base path for all icon attributes in the config. Default is null. - */ -mxDefaultPopupMenu.prototype.imageBasePath = null; - -/** - * Variable: config - * - * XML node used as the description of new menu items. This node is - * used in to dynamically create the menu items if their - * respective conditions evaluate to true for the given arguments. - */ -mxDefaultPopupMenu.prototype.config = null; - -/** - * Function: createMenu - * - * This function is called from to add items to the - * given menu based on . The config is a sequence of - * the following nodes and attributes. - * - * Child Nodes: - * - * add - Adds a new menu item. See below for attributes. - * separator - Adds a separator. No attributes. - * condition - Adds a custom condition. Name attribute. - * - * The add-node may have a child node that defines a function to be invoked - * before the action is executed (or instead of an action to be executed). - * - * Attributes: - * - * as - Resource key for the label (needs entry in property file). - * action - Name of the action to execute in enclosing editor. - * icon - Optional icon (relative/absolute URL). - * iconCls - Optional CSS class for the icon. - * if - Optional name of condition that must be true(see below). - * name - Name of custom condition. Only for condition nodes. - * - * Conditions: - * - * nocell - No cell under the mouse. - * ncells - More than one cell selected. - * notRoot - Drilling position is other than home. - * cell - Cell under the mouse. - * notEmpty - Exactly one cell with children under mouse. - * expandable - Exactly one expandable cell under mouse. - * collapsable - Exactly one collapsable cell under mouse. - * validRoot - Exactly one cell which is a possible root under mouse. - * swimlane - Exactly one cell which is a swimlane under mouse. - * - * Example: - * - * To add a new item for a given action to the popupmenu: - * - * (code) - * - * - * - * (end) - * - * To add a new item for a custom function: - * - * (code) - * - * - * - * (end) - * - * The above example invokes action1 with an additional third argument via - * the editor instance. The third argument is passed to the function that - * defines action1. If the add-node has no action-attribute, then only the - * function defined in the text content is executed, otherwise first the - * function and then the action defined in the action-attribute is - * executed. The function in the text content has 3 arguments, namely the - * instance, the instance under the mouse, and the - * native mouse event. - * - * Custom Conditions: - * - * To add a new condition for popupmenu items: - * - * (code) - * - * (end) - * - * The new condition can then be used in any item as follows: - * - * (code) - * - * (end) - * - * The order in which the items and conditions appear is not significant as - * all connditions are evaluated before any items are created. - * - * Parameters: - * - * editor - Enclosing instance. - * menu - that is used for adding items and separators. - * cell - Optional which is under the mousepointer. - * evt - Optional mouse event which triggered the menu. - */ -mxDefaultPopupMenu.prototype.createMenu = function(editor, menu, cell, evt) -{ - if (this.config != null) - { - var conditions = this.createConditions(editor, cell, evt); - var item = this.config.firstChild; - - this.addItems(editor, menu, cell, evt, conditions, item, null); - } -}; - -/** - * Function: addItems - * - * Recursively adds the given items and all of its children into the given menu. - * - * Parameters: - * - * editor - Enclosing instance. - * menu - that is used for adding items and separators. - * cell - Optional which is under the mousepointer. - * evt - Optional mouse event which triggered the menu. - * conditions - Array of names boolean conditions. - * item - XML node that represents the current menu item. - * parent - DOM node that represents the parent menu item. - */ -mxDefaultPopupMenu.prototype.addItems = function(editor, menu, cell, evt, conditions, item, parent) -{ - var addSeparator = false; - - while (item != null) - { - if (item.nodeName == 'add') - { - var condition = item.getAttribute('if'); - - if (condition == null || conditions[condition]) - { - var as = item.getAttribute('as'); - as = mxResources.get(as) || as; - var funct = mxUtils.eval(mxUtils.getTextContent(item)); - var action = item.getAttribute('action'); - var icon = item.getAttribute('icon'); - var iconCls = item.getAttribute('iconCls'); - - if (addSeparator) - { - menu.addSeparator(parent); - addSeparator = false; - } - - if (icon != null && this.imageBasePath) - { - icon = this.imageBasePath + icon; - } - - var row = this.addAction(menu, editor, as, icon, funct, action, cell, parent, iconCls); - this.addItems(editor, menu, cell, evt, conditions, item.firstChild, row); - } - } - else if (item.nodeName == 'separator') - { - addSeparator = true; - } - - item = item.nextSibling; - } -}; - -/** - * Function: addAction - * - * Helper method to bind an action to a new menu item. - * - * Parameters: - * - * menu - that is used for adding items and separators. - * editor - Enclosing instance. - * lab - String that represents the label of the menu item. - * icon - Optional URL that represents the icon of the menu item. - * action - Optional name of the action to execute in the given editor. - * funct - Optional function to execute before the optional action. The - * function takes an , the under the mouse and the - * mouse event that triggered the call. - * cell - Optional to use as an argument for the action. - * parent - DOM node that represents the parent menu item. - * iconCls - Optional CSS class for the menu icon. - */ -mxDefaultPopupMenu.prototype.addAction = function(menu, editor, lab, icon, funct, action, cell, parent, iconCls) -{ - var clickHandler = function(evt) - { - if (typeof(funct) == 'function') - { - funct.call(editor, editor, cell, evt); - } - - if (action != null) - { - editor.execute(action, cell, evt); - } - }; - - return menu.addItem(lab, icon, clickHandler, parent, iconCls); -}; - -/** - * Function: createConditions - * - * Evaluates the default conditions for the given context. - */ -mxDefaultPopupMenu.prototype.createConditions = function(editor, cell, evt) -{ - // Creates array with conditions - var model = editor.graph.getModel(); - var childCount = model.getChildCount(cell); - - // Adds some frequently used conditions - var conditions = []; - conditions['nocell'] = cell == null; - conditions['ncells'] = editor.graph.getSelectionCount() > 1; - conditions['notRoot'] = model.getRoot() != - model.getParent(editor.graph.getDefaultParent()); - conditions['cell'] = cell != null; - - var isCell = cell != null && editor.graph.getSelectionCount() == 1; - conditions['nonEmpty'] = isCell && childCount > 0; - conditions['expandable'] = isCell && editor.graph.isCellFoldable(cell, false); - conditions['collapsable'] = isCell && editor.graph.isCellFoldable(cell, true); - conditions['validRoot'] = isCell && editor.graph.isValidRoot(cell); - conditions['emptyValidRoot'] = conditions['validRoot'] && childCount == 0; - conditions['swimlane'] = isCell && editor.graph.isSwimlane(cell); - - // Evaluates dynamic conditions from config file - var condNodes = this.config.getElementsByTagName('condition'); - - for (var i=0; i to read configuration - * data into an existing instance. See for a - * description of the configuration format. - * - * Constructor: mxDefaultToolbar - * - * Constructs a new toolbar for the given container and editor. The - * container and editor may be null if a prototypical instance for a - * is created. - * - * Parameters: - * - * container - DOM node that contains the toolbar. - * editor - Reference to the enclosing . - */ -function mxDefaultToolbar(container, editor) -{ - this.editor = editor; - - if (container != null && - editor != null) - { - this.init(container); - } -}; - -/** - * Variable: editor - * - * Reference to the enclosing . - */ -mxDefaultToolbar.prototype.editor = null; - -/** - * Variable: toolbar - * - * Holds the internal . - */ -mxDefaultToolbar.prototype.toolbar = null; - -/** - * Variable: resetHandler - * - * Reference to the function used to reset the . - */ -mxDefaultToolbar.prototype.resetHandler = null; - -/** - * Variable: spacing - * - * Defines the spacing between existing and new vertices in - * gridSize units when a new vertex is dropped on an existing - * cell. Default is 4 (40 pixels). - */ -mxDefaultToolbar.prototype.spacing = 4; - -/** - * Variable: connectOnDrop - * - * Specifies if elements should be connected if new cells are dropped onto - * connectable elements. Default is false. - */ -mxDefaultToolbar.prototype.connectOnDrop = false; - -/** - * Variable: init - * - * Constructs the for the given container and installs a listener - * that updates the on if an item is - * selected in the toolbar. This assumes that is not null. - * - * Parameters: - * - * container - DOM node that contains the toolbar. - */ -mxDefaultToolbar.prototype.init = function(container) -{ - if (container != null) - { - this.toolbar = new mxToolbar(container); - - // Installs the insert function in the editor if an item is - // selected in the toolbar - this.toolbar.addListener(mxEvent.SELECT, - mxUtils.bind(this, function(sender, evt) - { - var funct = evt.getProperty('function'); - - if (funct != null) - { - this.editor.insertFunction = mxUtils.bind(this, function() - { - funct.apply(this, arguments); - this.toolbar.resetMode(); - }); - } - else - { - this.editor.insertFunction = null; - } - }) - ); - - // Resets the selected tool after a doubleclick or escape keystroke - this.resetHandler = mxUtils.bind(this, function() - { - if (this.toolbar != null) - { - this.toolbar.resetMode(true); - } - }); - - this.editor.graph.addListener(mxEvent.DOUBLE_CLICK, this.resetHandler); - this.editor.addListener(mxEvent.ESCAPE, this.resetHandler); - } -}; - -/** - * Function: addItem - * - * Adds a new item that executes the given action in . The title, - * icon and pressedIcon are used to display the toolbar item. - * - * Parameters: - * - * title - String that represents the title (tooltip) for the item. - * icon - URL of the icon to be used for displaying the item. - * action - Name of the action to execute when the item is clicked. - * pressed - Optional URL of the icon for the pressed state. - */ -mxDefaultToolbar.prototype.addItem = function(title, icon, action, pressed) -{ - var clickHandler = mxUtils.bind(this, function() - { - if (action != null && action.length > 0) - { - this.editor.execute(action); - } - }); - - return this.toolbar.addItem(title, icon, clickHandler, pressed); -}; - -/** - * Function: addSeparator - * - * Adds a vertical separator using the optional icon. - * - * Parameters: - * - * icon - Optional URL of the icon that represents the vertical separator. - * Default is + '/separator.gif'. - */ -mxDefaultToolbar.prototype.addSeparator = function(icon) -{ - icon = icon || mxClient.imageBasePath + '/separator.gif'; - this.toolbar.addSeparator(icon); -}; - -/** - * Function: addCombo - * - * Helper method to invoke on and return the - * resulting DOM node. - */ -mxDefaultToolbar.prototype.addCombo = function() -{ - return this.toolbar.addCombo(); -}; - -/** - * Function: addActionCombo - * - * Helper method to invoke on using - * the given title and return the resulting DOM node. - * - * Parameters: - * - * title - String that represents the title of the combo. - */ -mxDefaultToolbar.prototype.addActionCombo = function(title) -{ - return this.toolbar.addActionCombo(title); -}; - -/** - * Function: addActionOption - * - * Binds the given action to a option with the specified label in the - * given combo. Combo is an object returned from an earlier call to - * or . - * - * Parameters: - * - * combo - DOM node that represents the combo box. - * title - String that represents the title of the combo. - * action - Name of the action to execute in . - */ -mxDefaultToolbar.prototype.addActionOption = function(combo, title, action) -{ - var clickHandler = mxUtils.bind(this, function() - { - this.editor.execute(action); - }); - - this.addOption(combo, title, clickHandler); -}; - -/** - * Function: addOption - * - * Helper method to invoke on and return - * the resulting DOM node that represents the option. - * - * Parameters: - * - * combo - DOM node that represents the combo box. - * title - String that represents the title of the combo. - * value - Object that represents the value of the option. - */ -mxDefaultToolbar.prototype.addOption = function(combo, title, value) -{ - return this.toolbar.addOption(combo, title, value); -}; - -/** - * Function: addMode - * - * Creates an item for selecting the given mode in the 's graph. - * Supported modenames are select, connect and pan. - * - * Parameters: - * - * title - String that represents the title of the item. - * icon - URL of the icon that represents the item. - * mode - String that represents the mode name to be used in - * . - * pressed - Optional URL of the icon that represents the pressed state. - * funct - Optional JavaScript function that takes the as the - * first and only argument that is executed after the mode has been - * selected. - */ -mxDefaultToolbar.prototype.addMode = function(title, icon, mode, pressed, funct) -{ - var clickHandler = mxUtils.bind(this, function() - { - this.editor.setMode(mode); - - if (funct != null) - { - funct(this.editor); - } - }); - - return this.toolbar.addSwitchMode(title, icon, clickHandler, pressed); -}; - -/** - * Function: addPrototype - * - * Creates an item for inserting a clone of the specified prototype cell into - * the 's graph. The ptype may either be a cell or a function that - * returns a cell. - * - * Parameters: - * - * title - String that represents the title of the item. - * icon - URL of the icon that represents the item. - * ptype - Function or object that represents the prototype cell. If ptype - * is a function then it is invoked with no arguments to create new - * instances. - * pressed - Optional URL of the icon that represents the pressed state. - * insert - Optional JavaScript function that handles an insert of the new - * cell. This function takes the , new cell to be inserted, mouse - * event and optional under the mouse pointer as arguments. - * toggle - Optional boolean that specifies if the item can be toggled. - * Default is true. - */ -mxDefaultToolbar.prototype.addPrototype = function(title, icon, ptype, pressed, insert, toggle) -{ - // Creates a wrapper function that is in charge of constructing - // the new cell instance to be inserted into the graph - var factory = function() - { - if (typeof(ptype) == 'function') - { - return ptype(); - } - else if (ptype != null) - { - return ptype.clone(); - } - - return null; - }; - - // Defines the function for a click event on the graph - // after this item has been selected in the toolbar - var clickHandler = mxUtils.bind(this, function(evt, cell) - { - if (typeof(insert) == 'function') - { - insert(this.editor, factory(), evt, cell); - } - else - { - this.drop(factory(), evt, cell); - } - - this.toolbar.resetMode(); - mxEvent.consume(evt); - }); - - var img = this.toolbar.addMode(title, icon, clickHandler, pressed, null, toggle); - - // Creates a wrapper function that calls the click handler without - // the graph argument - var dropHandler = function(graph, evt, cell) - { - clickHandler(evt, cell); - }; - - this.installDropHandler(img, dropHandler); - - return img; -}; - -/** - * Function: drop - * - * Handles a drop from a toolbar item to the graph. The given vertex - * represents the new cell to be inserted. This invokes or - * depending on the given target cell. - * - * Parameters: - * - * vertex - to be inserted. - * evt - Mouse event that represents the drop. - * target - Optional that represents the drop target. - */ -mxDefaultToolbar.prototype.drop = function(vertex, evt, target) -{ - var graph = this.editor.graph; - var model = graph.getModel(); - - if (target == null || - model.isEdge(target) || - !this.connectOnDrop || - !graph.isCellConnectable(target)) - { - while (target != null && - !graph.isValidDropTarget(target, [vertex], evt)) - { - target = model.getParent(target); - } - - this.insert(vertex, evt, target); - } - else - { - this.connect(vertex, evt, target); - } -}; - -/** - * Function: insert - * - * Handles a drop by inserting the given vertex into the given parent cell - * or the default parent if no parent is specified. - * - * Parameters: - * - * vertex - to be inserted. - * evt - Mouse event that represents the drop. - * parent - Optional that represents the parent. - */ -mxDefaultToolbar.prototype.insert = function(vertex, evt, target) -{ - var graph = this.editor.graph; - - if (graph.canImportCell(vertex)) - { - var x = mxEvent.getClientX(evt); - var y = mxEvent.getClientY(evt); - var pt = mxUtils.convertPoint(graph.container, x, y); - - // Splits the target edge or inserts into target group - if (graph.isSplitEnabled() && - graph.isSplitTarget(target, [vertex], evt)) - { - return graph.splitEdge(target, [vertex], null, pt.x, pt.y); - } - else - { - return this.editor.addVertex(target, vertex, pt.x, pt.y); - } - } - - return null; -}; - -/** - * Function: connect - * - * Handles a drop by connecting the given vertex to the given source cell. - * - * vertex - to be inserted. - * evt - Mouse event that represents the drop. - * source - Optional that represents the source terminal. - */ -mxDefaultToolbar.prototype.connect = function(vertex, evt, source) -{ - var graph = this.editor.graph; - var model = graph.getModel(); - - if (source != null && - graph.isCellConnectable(vertex) && - graph.isEdgeValid(null, source, vertex)) - { - var edge = null; - - model.beginUpdate(); - try - { - var geo = model.getGeometry(source); - var g = model.getGeometry(vertex).clone(); - - // Moves the vertex away from the drop target that will - // be used as the source for the new connection - g.x = geo.x + (geo.width - g.width) / 2; - g.y = geo.y + (geo.height - g.height) / 2; - - var step = this.spacing * graph.gridSize; - var dist = model.getDirectedEdgeCount(source, true) * 20; - - if (this.editor.horizontalFlow) - { - g.x += (g.width + geo.width) / 2 + step + dist; - } - else - { - g.y += (g.height + geo.height) / 2 + step + dist; - } - - vertex.setGeometry(g); - - // Fires two add-events with the code below - should be fixed - // to only fire one add event for both inserts - var parent = model.getParent(source); - graph.addCell(vertex, parent); - graph.constrainChild(vertex); - - // Creates the edge using the editor instance and calls - // the second function that fires an add event - edge = this.editor.createEdge(source, vertex); - - if (model.getGeometry(edge) == null) - { - var edgeGeometry = new mxGeometry(); - edgeGeometry.relative = true; - - model.setGeometry(edge, edgeGeometry); - } - - graph.addEdge(edge, parent, source, vertex); - } - finally - { - model.endUpdate(); - } - - graph.setSelectionCells([vertex, edge]); - graph.scrollCellToVisible(vertex); - } -}; - -/** - * Function: installDropHandler - * - * Makes the given img draggable using the given function for handling a - * drop event. - * - * Parameters: - * - * img - DOM node that represents the image. - * dropHandler - Function that handles a drop of the image. - */ -mxDefaultToolbar.prototype.installDropHandler = function (img, dropHandler) -{ - var sprite = document.createElement('img'); - sprite.setAttribute('src', img.getAttribute('src')); - - // Handles delayed loading of the images - var loader = mxUtils.bind(this, function(evt) - { - // Preview uses the image node with double size. Later this can be - // changed to use a separate preview and guides, but for this the - // dropHandler must use the additional x- and y-arguments and the - // dragsource which makeDraggable returns much be configured to - // use guides via mxDragSource.isGuidesEnabled. - sprite.style.width = (2 * img.offsetWidth) + 'px'; - sprite.style.height = (2 * img.offsetHeight) + 'px'; - - mxUtils.makeDraggable(img, this.editor.graph, dropHandler, - sprite); - mxEvent.removeListener(sprite, 'load', loader); - }); - - if (mxClient.IS_IE) - { - loader(); - } - else - { - mxEvent.addListener(sprite, 'load', loader); - } -}; - -/** - * Function: destroy - * - * Destroys the associated with this object and removes all - * installed listeners. This does normally not need to be called, the - * is destroyed automatically when the window unloads (in IE) by - * . - */ -mxDefaultToolbar.prototype.destroy = function () -{ - if (this.resetHandler != null) - { - this.editor.graph.removeListener('dblclick', this.resetHandler); - this.editor.removeListener('escape', this.resetHandler); - this.resetHandler = null; - } - - if (this.toolbar != null) - { - this.toolbar.destroy(); - this.toolbar = null; - } -}; diff --git a/src/js/editor/mxEditor.js b/src/js/editor/mxEditor.js deleted file mode 100644 index 9c57a9c..0000000 --- a/src/js/editor/mxEditor.js +++ /dev/null @@ -1,3220 +0,0 @@ -/** - * $Id: mxEditor.js,v 1.231 2012-12-03 18:02:25 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxEditor - * - * Extends to implement a application wrapper for a graph that - * adds , I/O using , auto-layout using , - * command history using , and standard dialogs and widgets, eg. - * properties, help, outline, toolbar, and popupmenu. It also adds - * to be used as cells in toolbars, auto-validation using the - * flag, attribute cycling using , higher-level events - * such as , and backend integration using , , - * , and . - * - * Actions: - * - * Actions are functions stored in the array under their names. The - * functions take the as the first, and an optional as the - * second argument and are invoked using . Any additional arguments - * passed to execute are passed on to the action as-is. - * - * A list of built-in actions is available in the description. - * - * Read/write Diagrams: - * - * To read a diagram from an XML string, for example from a textfield within the - * page, the following code is used: - * - * (code) - * var doc = mxUtils.parseXML(xmlString); - * var node = doc.documentElement; - * editor.readGraphModel(node); - * (end) - * - * For reading a diagram from a remote location, use the method. - * - * To save diagrams in XML on a server, you can set the variable. - * This variable will be used in to construct a URL for the post - * request that is issued in the method. The post request contains the - * XML representation of the diagram as returned by in the - * xml parameter. - * - * On the server side, the post request is processed using standard - * technologies such as Java Servlets, CGI, .NET or ASP. - * - * Here are some examples of processing a post request in various languages. - * - * - Java: URLDecoder.decode(request.getParameter("xml"), "UTF-8").replace("\n", " ") - * - * Note that the linefeeds should only be replaced if the XML is - * processed in Java, for example when creating an image, but not - * if the XML is passed back to the client-side. - * - * - .NET: HttpUtility.UrlDecode(context.Request.Params["xml"]) - * - PHP: urldecode($_POST["xml"]) - * - * Creating images: - * - * A backend (Java, PHP or C#) is required for creating images. The - * distribution contains an example for each backend (ImageHandler.java, - * ImageHandler.cs and graph.php). More information about using a backend - * to create images can be found in the readme.html files. Note that the - * preview is implemented using VML/SVG in the browser and does not require - * a backend. The backend is only required to creates images (bitmaps). - * - * Special characters: - * - * Note There are five characters that should always appear in XML content as - * escapes, so that they do not interact with the syntax of the markup. These - * are part of the language for all documents based on XML and for HTML. - * - * - < (<) - * - > (>) - * - & (&) - * - " (") - * - ' (') - * - * Although it is part of the XML language, ' is not defined in HTML. - * For this reason the XHTML specification recommends instead the use of - * ' if text may be passed to a HTML user agent. - * - * If you are having problems with special characters on the server-side then - * you may want to try the flag. - * - * For converting decimal escape sequences inside strings, a user has provided - * us with the following function: - * - * (code) - * function html2js(text) - * { - * var entitySearch = /&#[0-9]+;/; - * var entity; - * - * while (entity = entitySearch.exec(text)) - * { - * var charCode = entity[0].substring(2, entity[0].length -1); - * text = text.substring(0, entity.index) - * + String.fromCharCode(charCode) - * + text.substring(entity.index + entity[0].length); - * } - * - * return text; - * } - * (end) - * - * Otherwise try using hex escape sequences and the built-in unescape function - * for converting such strings. - * - * Local Files: - * - * For saving and opening local files, no standardized method exists that - * works across all browsers. The recommended way of dealing with local files - * is to create a backend that streams the XML data back to the browser (echo) - * as an attachment so that a Save-dialog is displayed on the client-side and - * the file can be saved to the local disk. - * - * For example, in PHP the code that does this looks as follows. - * - * (code) - * $xml = stripslashes($_POST["xml"]); - * header("Content-Disposition: attachment; filename=\"diagram.xml\""); - * echo($xml); - * (end) - * - * To open a local file, the file should be uploaded via a form in the browser - * and then opened from the server in the editor. - * - * Cell Properties: - * - * The properties displayed in the properties dialog are the attributes and - * values of the cell's user object, which is an XML node. The XML node is - * defined in the templates section of the config file. - * - * The templates are stored in and contain cells which - * are cloned at insertion time to create new vertices by use of drag and - * drop from the toolbar. Each entry in the toolbar for adding a new vertex - * must refer to an existing template. - * - * In the following example, the task node is a business object and only the - * mxCell node and its mxGeometry child contain graph information: - * - * (code) - * - * - * - * - * - * (end) - * - * The idea is that the XML representation is inverse from the in-memory - * representation: The outer XML node is the user object and the inner node is - * the cell. This means the user object of the cell is the Task node with no - * children for the above example: - * - * (code) - * - * (end) - * - * The Task node can have any tag name, attributes and child nodes. The - * will use the XML hierarchy as the user object, while removing the - * "known annotations", such as the mxCell node. At save-time the cell data - * will be "merged" back into the user object. The user object is only modified - * via the properties dialog during the lifecycle of the cell. - * - * In the default implementation of , the user object's - * attributes are put into a form for editing. Attributes are changed using - * the action in the model. The dialog can be replaced - * by overriding the hook or by replacing the showProperties - * action in . Alternatively, the entry in the config file's popupmenu - * section can be modified to invoke a different action. - * - * If you want to displey the properties dialog on a doubleclick, you can set - * to showProperties as follows: - * - * (code) - * editor.dblClickAction = 'showProperties'; - * (end) - * - * Popupmenu and Toolbar: - * - * The toolbar and popupmenu are typically configured using the respective - * sections in the config file, that is, the popupmenu is defined as follows: - * - * (code) - * - * - * - * ... - * (end) - * - * New entries can be added to the toolbar by inserting an add-node into the - * above configuration. Existing entries may be removed and changed by - * modifying or removing the respective entries in the configuration. - * The configuration is read by the , the format of the - * configuration is explained in . - * - * The toolbar is defined in the mxDefaultToolbar section. Items can be added - * and removed in this section. - * - * (code) - * - * - * - * - * ... - * (end) - * - * The format of the configuration is described in - * . - * - * Ids: - * - * For the IDs, there is an implicit behaviour in : It moves the Id - * from the cell to the user object at encoding time and vice versa at decoding - * time. For example, if the Task node from above has an id attribute, then - * the of the corresponding cell will have this value. If there - * is no Id collision in the model, then the cell may be retrieved using this - * Id with the function. If there is a collision, a new - * Id will be created for the cell using . At encoding - * time, this new Id will replace the value previously stored under the id - * attribute in the Task node. - * - * See , and - * for information about configuring the editor and user interface. - * - * Programmatically inserting cells: - * - * For inserting a new cell, say, by clicking a button in the document, - * the following code can be used. This requires an reference to the editor. - * - * (code) - * var userObject = new Object(); - * var parent = editor.graph.getDefaultParent(); - * var model = editor.graph.model; - * model.beginUpdate(); - * try - * { - * editor.graph.insertVertex(parent, null, userObject, 20, 20, 80, 30); - * } - * finally - * { - * model.endUpdate(); - * } - * (end) - * - * If a template cell from the config file should be inserted, then a clone - * of the template can be created as follows. The clone is then inserted using - * the add function instead of addVertex. - * - * (code) - * var template = editor.templates['task']; - * var clone = editor.graph.model.cloneCell(template); - * (end) - * - * Resources: - * - * resources/editor - Language resources for mxEditor - * - * Callback: onInit - * - * Called from within the constructor. In the callback, - * "this" refers to the editor instance. - * - * Cookie: mxgraph=seen - * - * Set when the editor is started. Never expires. Use - * to reset this cookie. This cookie - * only exists if is implemented. - * - * Event: mxEvent.OPEN - * - * Fires after a file was opened in . The filename property - * contains the filename that was used. The same value is also available in - * . - * - * Event: mxEvent.SAVE - * - * Fires after the current file was saved in . The url - * property contains the URL that was used for saving. - * - * Event: mxEvent.POST - * - * Fires if a successful response was received in . The - * request property contains the , the - * url and data properties contain the URL and the - * data that were used in the post request. - * - * Event: mxEvent.ROOT - * - * Fires when the current root has changed, or when the title of the current - * root has changed. This event has no properties. - * - * Event: mxEvent.SESSION - * - * Fires when anything in the session has changed. The session - * property contains the respective . - * - * Event: mxEvent.BEFORE_ADD_VERTEX - * - * Fires before a vertex is added in . The vertex - * property contains the new vertex and the parent property - * contains its parent. - * - * Event: mxEvent.ADD_VERTEX - * - * Fires between begin- and endUpdate in . The vertex - * property contains the vertex that is being inserted. - * - * Event: mxEvent.AFTER_ADD_VERTEX - * - * Fires after a vertex was inserted and selected in . The - * vertex property contains the new vertex. - * - * Example: - * - * For starting an in-place edit after a new vertex has been added to the - * graph, the following code can be used. - * - * (code) - * editor.addListener(mxEvent.AFTER_ADD_VERTEX, function(sender, evt) - * { - * var vertex = evt.getProperty('vertex'); - * - * if (editor.graph.isCellEditable(vertex)) - * { - * editor.graph.startEditingAtCell(vertex); - * } - * }); - * (end) - * - * Event: mxEvent.ESCAPE - * - * Fires when the escape key is pressed. The event property - * contains the key event. - * - * Constructor: mxEditor - * - * Constructs a new editor. This function invokes the callback - * upon completion. - * - * Example: - * - * (code) - * var config = mxUtils.load('config/diagrameditor.xml').getDocumentElement(); - * var editor = new mxEditor(config); - * (end) - * - * Parameters: - * - * config - Optional XML node that contains the configuration. - */ -function mxEditor(config) -{ - this.actions = []; - this.addActions(); - - // Executes the following only if a document has been instanciated. - // That is, don't execute when the editorcodec is setup. - if (document.body != null) - { - // Defines instance fields - this.cycleAttributeValues = []; - this.popupHandler = new mxDefaultPopupMenu(); - this.undoManager = new mxUndoManager(); - - // Creates the graph and toolbar without the containers - this.graph = this.createGraph(); - this.toolbar = this.createToolbar(); - - // Creates the global keyhandler (requires graph instance) - this.keyHandler = new mxDefaultKeyHandler(this); - - // Configures the editor using the URI - // which was passed to the ctor - this.configure(config); - - // Assigns the swimlaneIndicatorColorAttribute on the graph - this.graph.swimlaneIndicatorColorAttribute = this.cycleAttributeName; - - // Initializes the session if the urlInit - // member field of this editor is set. - if (!mxClient.IS_LOCAL && this.urlInit != null) - { - this.session = this.createSession(); - } - - // Checks ifthe hook has been set - if (this.onInit != null) - { - // Invokes the hook - this.onInit(); - } - - // Automatic deallocation of memory - if (mxClient.IS_IE) - { - mxEvent.addListener(window, 'unload', mxUtils.bind(this, function() - { - this.destroy(); - })); - } - } -}; - -/** - * Installs the required language resources at class - * loading time. - */ -if (mxLoadResources) -{ - mxResources.add(mxClient.basePath+'/resources/editor'); -} - -/** - * Extends mxEventSource. - */ -mxEditor.prototype = new mxEventSource(); -mxEditor.prototype.constructor = mxEditor; - -/** - * Group: Controls and Handlers - */ - -/** - * Variable: askZoomResource - * - * Specifies the resource key for the zoom dialog. If the resource for this - * key does not exist then the value is used as the error message. Default - * is 'askZoom'. - */ -mxEditor.prototype.askZoomResource = (mxClient.language != 'none') ? 'askZoom' : ''; - -/** - * Variable: lastSavedResource - * - * Specifies the resource key for the last saved info. If the resource for - * this key does not exist then the value is used as the error message. - * Default is 'lastSaved'. - */ -mxEditor.prototype.lastSavedResource = (mxClient.language != 'none') ? 'lastSaved' : ''; - -/** - * Variable: currentFileResource - * - * Specifies the resource key for the current file info. If the resource for - * this key does not exist then the value is used as the error message. - * Default is 'lastSaved'. - */ -mxEditor.prototype.currentFileResource = (mxClient.language != 'none') ? 'currentFile' : ''; - -/** - * Variable: propertiesResource - * - * Specifies the resource key for the properties window title. If the - * resource for this key does not exist then the value is used as the - * error message. Default is 'properties'. - */ -mxEditor.prototype.propertiesResource = (mxClient.language != 'none') ? 'properties' : ''; - -/** - * Variable: tasksResource - * - * Specifies the resource key for the tasks window title. If the - * resource for this key does not exist then the value is used as the - * error message. Default is 'tasks'. - */ -mxEditor.prototype.tasksResource = (mxClient.language != 'none') ? 'tasks' : ''; - -/** - * Variable: helpResource - * - * Specifies the resource key for the help window title. If the - * resource for this key does not exist then the value is used as the - * error message. Default is 'help'. - */ -mxEditor.prototype.helpResource = (mxClient.language != 'none') ? 'help' : ''; - -/** - * Variable: outlineResource - * - * Specifies the resource key for the outline window title. If the - * resource for this key does not exist then the value is used as the - * error message. Default is 'outline'. - */ -mxEditor.prototype.outlineResource = (mxClient.language != 'none') ? 'outline' : ''; - -/** - * Variable: outline - * - * Reference to the that contains the outline. The - * is stored in outline.outline. - */ -mxEditor.prototype.outline = null; - -/** - * Variable: graph - * - * Holds a for displaying the diagram. The graph - * is created in . - */ -mxEditor.prototype.graph = null; - -/** - * Variable: graphRenderHint - * - * Holds the render hint used for creating the - * graph in . See . - * Default is null. - */ -mxEditor.prototype.graphRenderHint = null; - -/** - * Variable: toolbar - * - * Holds a for displaying the toolbar. The - * toolbar is created in . - */ -mxEditor.prototype.toolbar = null; - -/** - * Variable: session - * - * Holds a instance associated with this editor. - */ -mxEditor.prototype.session = null; - -/** - * Variable: status - * - * DOM container that holds the statusbar. Default is null. - * Use to set this value. - */ -mxEditor.prototype.status = null; - -/** - * Variable: popupHandler - * - * Holds a for displaying - * popupmenus. - */ -mxEditor.prototype.popupHandler = null; - -/** - * Variable: undoManager - * - * Holds an for the command history. - */ -mxEditor.prototype.undoManager = null; - -/** - * Variable: keyHandler - * - * Holds a for handling keyboard events. - * The handler is created in . - */ -mxEditor.prototype.keyHandler = null; - -/** - * Group: Actions and Options - */ - -/** - * Variable: actions - * - * Maps from actionnames to actions, which are functions taking - * the editor and the cell as arguments. Use - * to add or replace an action and to execute an action - * by name, passing the cell to be operated upon as the second - * argument. - */ -mxEditor.prototype.actions = null; - -/** - * Variable: dblClickAction - * - * Specifies the name of the action to be executed - * when a cell is double clicked. Default is edit. - * - * To handle a singleclick, use the following code. - * - * (code) - * editor.graph.addListener(mxEvent.CLICK, function(sender, evt) - * { - * var e = evt.getProperty('event'); - * var cell = evt.getProperty('cell'); - * - * if (cell != null && !e.isConsumed()) - * { - * // Do something useful with cell... - * e.consume(); - * } - * }); - * (end) - */ -mxEditor.prototype.dblClickAction = 'edit'; - -/** - * Variable: swimlaneRequired - * - * Specifies if new cells must be inserted - * into an existing swimlane. Otherwise, cells - * that are not swimlanes can be inserted as - * top-level cells. Default is false. - */ -mxEditor.prototype.swimlaneRequired = false; - -/** - * Variable: disableContextMenu - * - * Specifies if the context menu should be disabled in the graph container. - * Default is true. - */ -mxEditor.prototype.disableContextMenu = true; - -/** - * Group: Templates - */ - -/** - * Variable: insertFunction - * - * Specifies the function to be used for inserting new - * cells into the graph. This is assigned from the - * if a vertex-tool is clicked. - */ -mxEditor.prototype.insertFunction = null; - -/** - * Variable: forcedInserting - * - * Specifies if a new cell should be inserted on a single - * click even using if there is a cell - * under the mousepointer, otherwise the cell under the - * mousepointer is selected. Default is false. - */ -mxEditor.prototype.forcedInserting = false; - -/** - * Variable: templates - * - * Maps from names to protoype cells to be used - * in the toolbar for inserting new cells into - * the diagram. - */ -mxEditor.prototype.templates = null; - -/** - * Variable: defaultEdge - * - * Prototype edge cell that is used for creating - * new edges. - */ -mxEditor.prototype.defaultEdge = null; - -/** - * Variable: defaultEdgeStyle - * - * Specifies the edge style to be returned in . - * Default is null. - */ -mxEditor.prototype.defaultEdgeStyle = null; - -/** - * Variable: defaultGroup - * - * Prototype group cell that is used for creating - * new groups. - */ -mxEditor.prototype.defaultGroup = null; - -/** - * Variable: graphRenderHint - * - * Default size for the border of new groups. If null, - * then then is used. Default is - * null. - */ -mxEditor.prototype.groupBorderSize = null; - -/** - * Group: Backend Integration - */ - -/** - * Variable: filename - * - * Contains the URL of the last opened file as a string. - * Default is null. - */ -mxEditor.prototype.filename = null; - -/** - * Variable: lineFeed - * - * Character to be used for encoding linefeeds in . Default is ' '. - */ -mxEditor.prototype.linefeed = ' '; - -/** - * Variable: postParameterName - * - * Specifies if the name of the post parameter that contains the diagram - * data in a post request to the server. Default is xml. - */ -mxEditor.prototype.postParameterName = 'xml'; - -/** - * Variable: escapePostData - * - * Specifies if the data in the post request for saving a diagram - * should be converted using encodeURIComponent. Default is true. - */ -mxEditor.prototype.escapePostData = true; - -/** - * Variable: urlPost - * - * Specifies the URL to be used for posting the diagram - * to a backend in . - */ -mxEditor.prototype.urlPost = null; - -/** - * Variable: urlImage - * - * Specifies the URL to be used for creating a bitmap of - * the graph in the image action. - */ -mxEditor.prototype.urlImage = null; - -/** - * Variable: urlInit - * - * Specifies the URL to be used for initializing the session. - */ -mxEditor.prototype.urlInit = null; - -/** - * Variable: urlNotify - * - * Specifies the URL to be used for notifying the backend - * in the session. - */ -mxEditor.prototype.urlNotify = null; - -/** - * Variable: urlPoll - * - * Specifies the URL to be used for polling in the session. - */ -mxEditor.prototype.urlPoll = null; - -/** - * Group: Autolayout - */ - -/** - * Variable: horizontalFlow - * - * Specifies the direction of the flow - * in the diagram. This is used in the - * layout algorithms. Default is false, - * ie. vertical flow. - */ -mxEditor.prototype.horizontalFlow = false; - -/** - * Variable: layoutDiagram - * - * Specifies if the top-level elements in the - * diagram should be layed out using a vertical - * or horizontal stack depending on the setting - * of . The spacing between the - * swimlanes is specified by . - * Default is false. - * - * If the top-level elements are swimlanes, then - * the intra-swimlane layout is activated by - * the switch. - */ -mxEditor.prototype.layoutDiagram = false; - -/** - * Variable: swimlaneSpacing - * - * Specifies the spacing between swimlanes if - * automatic layout is turned on in - * . Default is 0. - */ -mxEditor.prototype.swimlaneSpacing = 0; - -/** - * Variable: maintainSwimlanes - * - * Specifies if the swimlanes should be kept at the same - * width or height depending on the setting of - * . Default is false. - * - * For horizontal flows, all swimlanes - * have the same height and for vertical flows, all swimlanes - * have the same width. Furthermore, the swimlanes are - * automatically "stacked" if is true. - */ -mxEditor.prototype.maintainSwimlanes = false; - -/** - * Variable: layoutSwimlanes - * - * Specifies if the children of swimlanes should - * be layed out, either vertically or horizontally - * depending on . - * Default is false. - */ -mxEditor.prototype.layoutSwimlanes = false; - -/** - * Group: Attribute Cycling - */ - -/** - * Variable: cycleAttributeValues - * - * Specifies the attribute values to be cycled when - * inserting new swimlanes. Default is an empty - * array. - */ -mxEditor.prototype.cycleAttributeValues = null; - -/** - * Variable: cycleAttributeIndex - * - * Index of the last consumed attribute index. If a new - * swimlane is inserted, then the - * at this index will be used as the value for - * . Default is 0. - */ -mxEditor.prototype.cycleAttributeIndex = 0; - -/** - * Variable: cycleAttributeName - * - * Name of the attribute to be assigned a - * when inserting new swimlanes. Default is fillColor. - */ -mxEditor.prototype.cycleAttributeName = 'fillColor'; - -/** - * Group: Windows - */ - -/** - * Variable: tasks - * - * Holds the created in . - */ -mxEditor.prototype.tasks = null; - -/** - * Variable: tasksWindowImage - * - * Icon for the tasks window. - */ -mxEditor.prototype.tasksWindowImage = null; - -/** - * Variable: tasksTop - * - * Specifies the top coordinate of the tasks window in pixels. - * Default is 20. - */ -mxEditor.prototype.tasksTop = 20; - -/** - * Variable: help - * - * Holds the created in . - */ -mxEditor.prototype.help = null; - -/** - * Variable: helpWindowImage - * - * Icon for the help window. - */ -mxEditor.prototype.helpWindowImage = null; - -/** - * Variable: urlHelp - * - * Specifies the URL to be used for the contents of the - * Online Help window. This is usually specified in the - * resources file under urlHelp for language-specific - * online help support. - */ -mxEditor.prototype.urlHelp = null; - -/** - * Variable: helpWidth - * - * Specifies the width of the help window in pixels. - * Default is 300. - */ -mxEditor.prototype.helpWidth = 300; - -/** - * Variable: helpWidth - * - * Specifies the width of the help window in pixels. - * Default is 260. - */ -mxEditor.prototype.helpHeight = 260; - -/** - * Variable: propertiesWidth - * - * Specifies the width of the properties window in pixels. - * Default is 240. - */ -mxEditor.prototype.propertiesWidth = 240; - -/** - * Variable: propertiesHeight - * - * Specifies the height of the properties window in pixels. - * If no height is specified then the window will be automatically - * sized to fit its contents. Default is null. - */ -mxEditor.prototype.propertiesHeight = null; - -/** - * Variable: movePropertiesDialog - * - * Specifies if the properties dialog should be automatically - * moved near the cell it is displayed for, otherwise the - * dialog is not moved. This value is only taken into - * account if the dialog is already visible. Default is false. - */ -mxEditor.prototype.movePropertiesDialog = false; - -/** - * Variable: validating - * - * Specifies if should automatically be invoked after - * each change. Default is false. - */ -mxEditor.prototype.validating = false; - -/** - * Variable: modified - * - * True if the graph has been modified since it was last saved. - */ -mxEditor.prototype.modified = false; - -/** - * Function: isModified - * - * Returns . - */ -mxEditor.prototype.isModified = function () -{ - return this.modified; -}; - -/** - * Function: setModified - * - * Sets to the specified boolean value. - */ -mxEditor.prototype.setModified = function (value) -{ - this.modified = value; -}; - -/** - * Function: addActions - * - * Adds the built-in actions to the editor instance. - * - * save - Saves the graph using . - * print - Shows the graph in a new print preview window. - * show - Shows the graph in a new window. - * exportImage - Shows the graph as a bitmap image using . - * refresh - Refreshes the graph's display. - * cut - Copies the current selection into the clipboard - * and removes it from the graph. - * copy - Copies the current selection into the clipboard. - * paste - Pastes the clipboard into the graph. - * delete - Removes the current selection from the graph. - * group - Puts the current selection into a new group. - * ungroup - Removes the selected groups and selects the children. - * undo - Undoes the last change on the graph model. - * redo - Redoes the last change on the graph model. - * zoom - Sets the zoom via a dialog. - * zoomIn - Zooms into the graph. - * zoomOut - Zooms out of the graph - * actualSize - Resets the scale and translation on the graph. - * fit - Changes the scale so that the graph fits into the window. - * showProperties - Shows the properties dialog. - * selectAll - Selects all cells. - * selectNone - Clears the selection. - * selectVertices - Selects all vertices. - * selectEdges = Selects all edges. - * edit - Starts editing the current selection cell. - * enterGroup - Drills down into the current selection cell. - * exitGroup - Moves up in the drilling hierachy - * home - Moves to the topmost parent in the drilling hierarchy - * selectPrevious - Selects the previous cell. - * selectNext - Selects the next cell. - * selectParent - Selects the parent of the selection cell. - * selectChild - Selects the first child of the selection cell. - * collapse - Collapses the currently selected cells. - * expand - Expands the currently selected cells. - * bold - Toggle bold text style. - * italic - Toggle italic text style. - * underline - Toggle underline text style. - * shadow - Toggle shadow text style. - * alignCellsLeft - Aligns the selection cells at the left. - * alignCellsCenter - Aligns the selection cells in the center. - * alignCellsRight - Aligns the selection cells at the right. - * alignCellsTop - Aligns the selection cells at the top. - * alignCellsMiddle - Aligns the selection cells in the middle. - * alignCellsBottom - Aligns the selection cells at the bottom. - * alignFontLeft - Sets the horizontal text alignment to left. - * alignFontCenter - Sets the horizontal text alignment to center. - * alignFontRight - Sets the horizontal text alignment to right. - * alignFontTop - Sets the vertical text alignment to top. - * alignFontMiddle - Sets the vertical text alignment to middle. - * alignFontBottom - Sets the vertical text alignment to bottom. - * toggleTasks - Shows or hides the tasks window. - * toggleHelp - Shows or hides the help window. - * toggleOutline - Shows or hides the outline window. - * toggleConsole - Shows or hides the console window. - */ -mxEditor.prototype.addActions = function () -{ - this.addAction('save', function(editor) - { - editor.save(); - }); - - this.addAction('print', function(editor) - { - var preview = new mxPrintPreview(editor.graph, 1); - preview.open(); - }); - - this.addAction('show', function(editor) - { - mxUtils.show(editor.graph, null, 10, 10); - }); - - this.addAction('exportImage', function(editor) - { - var url = editor.getUrlImage(); - - if (url == null || mxClient.IS_LOCAL) - { - editor.execute('show'); - } - else - { - var node = mxUtils.getViewXml(editor.graph, 1); - var xml = mxUtils.getXml(node, '\n'); - - mxUtils.submit(url, editor.postParameterName + '=' + - encodeURIComponent(xml), document, '_blank'); - } - }); - - this.addAction('refresh', function(editor) - { - editor.graph.refresh(); - }); - - this.addAction('cut', function(editor) - { - if (editor.graph.isEnabled()) - { - mxClipboard.cut(editor.graph); - } - }); - - this.addAction('copy', function(editor) - { - if (editor.graph.isEnabled()) - { - mxClipboard.copy(editor.graph); - } - }); - - this.addAction('paste', function(editor) - { - if (editor.graph.isEnabled()) - { - mxClipboard.paste(editor.graph); - } - }); - - this.addAction('delete', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.removeCells(); - } - }); - - this.addAction('group', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.setSelectionCell(editor.groupCells()); - } - }); - - this.addAction('ungroup', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.setSelectionCells(editor.graph.ungroupCells()); - } - }); - - this.addAction('removeFromParent', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.removeCellsFromParent(); - } - }); - - this.addAction('undo', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.undo(); - } - }); - - this.addAction('redo', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.redo(); - } - }); - - this.addAction('zoomIn', function(editor) - { - editor.graph.zoomIn(); - }); - - this.addAction('zoomOut', function(editor) - { - editor.graph.zoomOut(); - }); - - this.addAction('actualSize', function(editor) - { - editor.graph.zoomActual(); - }); - - this.addAction('fit', function(editor) - { - editor.graph.fit(); - }); - - this.addAction('showProperties', function(editor, cell) - { - editor.showProperties(cell); - }); - - this.addAction('selectAll', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.selectAll(); - } - }); - - this.addAction('selectNone', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.clearSelection(); - } - }); - - this.addAction('selectVertices', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.selectVertices(); - } - }); - - this.addAction('selectEdges', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.selectEdges(); - } - }); - - this.addAction('edit', function(editor, cell) - { - if (editor.graph.isEnabled() && - editor.graph.isCellEditable(cell)) - { - editor.graph.startEditingAtCell(cell); - } - }); - - this.addAction('toBack', function(editor, cell) - { - if (editor.graph.isEnabled()) - { - editor.graph.orderCells(true); - } - }); - - this.addAction('toFront', function(editor, cell) - { - if (editor.graph.isEnabled()) - { - editor.graph.orderCells(false); - } - }); - - this.addAction('enterGroup', function(editor, cell) - { - editor.graph.enterGroup(cell); - }); - - this.addAction('exitGroup', function(editor) - { - editor.graph.exitGroup(); - }); - - this.addAction('home', function(editor) - { - editor.graph.home(); - }); - - this.addAction('selectPrevious', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.selectPreviousCell(); - } - }); - - this.addAction('selectNext', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.selectNextCell(); - } - }); - - this.addAction('selectParent', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.selectParentCell(); - } - }); - - this.addAction('selectChild', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.selectChildCell(); - } - }); - - this.addAction('collapse', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.foldCells(true); - } - }); - - this.addAction('collapseAll', function(editor) - { - if (editor.graph.isEnabled()) - { - var cells = editor.graph.getChildVertices(); - editor.graph.foldCells(true, false, cells); - } - }); - - this.addAction('expand', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.foldCells(false); - } - }); - - this.addAction('expandAll', function(editor) - { - if (editor.graph.isEnabled()) - { - var cells = editor.graph.getChildVertices(); - editor.graph.foldCells(false, false, cells); - } - }); - - this.addAction('bold', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.toggleCellStyleFlags( - mxConstants.STYLE_FONTSTYLE, - mxConstants.FONT_BOLD); - } - }); - - this.addAction('italic', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.toggleCellStyleFlags( - mxConstants.STYLE_FONTSTYLE, - mxConstants.FONT_ITALIC); - } - }); - - this.addAction('underline', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.toggleCellStyleFlags( - mxConstants.STYLE_FONTSTYLE, - mxConstants.FONT_UNDERLINE); - } - }); - - this.addAction('shadow', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.toggleCellStyleFlags( - mxConstants.STYLE_FONTSTYLE, - mxConstants.FONT_SHADOW); - } - }); - - this.addAction('alignCellsLeft', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.alignCells(mxConstants.ALIGN_LEFT); - } - }); - - this.addAction('alignCellsCenter', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.alignCells(mxConstants.ALIGN_CENTER); - } - }); - - this.addAction('alignCellsRight', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.alignCells(mxConstants.ALIGN_RIGHT); - } - }); - - this.addAction('alignCellsTop', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.alignCells(mxConstants.ALIGN_TOP); - } - }); - - this.addAction('alignCellsMiddle', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.alignCells(mxConstants.ALIGN_MIDDLE); - } - }); - - this.addAction('alignCellsBottom', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.alignCells(mxConstants.ALIGN_BOTTOM); - } - }); - - this.addAction('alignFontLeft', function(editor) - { - - editor.graph.setCellStyles( - mxConstants.STYLE_ALIGN, - mxConstants.ALIGN_LEFT); - }); - - this.addAction('alignFontCenter', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.setCellStyles( - mxConstants.STYLE_ALIGN, - mxConstants.ALIGN_CENTER); - } - }); - - this.addAction('alignFontRight', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.setCellStyles( - mxConstants.STYLE_ALIGN, - mxConstants.ALIGN_RIGHT); - } - }); - - this.addAction('alignFontTop', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.setCellStyles( - mxConstants.STYLE_VERTICAL_ALIGN, - mxConstants.ALIGN_TOP); - } - }); - - this.addAction('alignFontMiddle', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.setCellStyles( - mxConstants.STYLE_VERTICAL_ALIGN, - mxConstants.ALIGN_MIDDLE); - } - }); - - this.addAction('alignFontBottom', function(editor) - { - if (editor.graph.isEnabled()) - { - editor.graph.setCellStyles( - mxConstants.STYLE_VERTICAL_ALIGN, - mxConstants.ALIGN_BOTTOM); - } - }); - - this.addAction('zoom', function(editor) - { - var current = editor.graph.getView().scale*100; - var scale = parseFloat(mxUtils.prompt( - mxResources.get(editor.askZoomResource) || - editor.askZoomResource, - current))/100; - - if (!isNaN(scale)) - { - editor.graph.getView().setScale(scale); - } - }); - - this.addAction('toggleTasks', function(editor) - { - if (editor.tasks != null) - { - editor.tasks.setVisible(!editor.tasks.isVisible()); - } - else - { - editor.showTasks(); - } - }); - - this.addAction('toggleHelp', function(editor) - { - if (editor.help != null) - { - editor.help.setVisible(!editor.help.isVisible()); - } - else - { - editor.showHelp(); - } - }); - - this.addAction('toggleOutline', function(editor) - { - if (editor.outline == null) - { - editor.showOutline(); - } - else - { - editor.outline.setVisible(!editor.outline.isVisible()); - } - }); - - this.addAction('toggleConsole', function(editor) - { - mxLog.setVisible(!mxLog.isVisible()); - }); -}; - -/** - * Function: createSession - * - * Creates and returns and using , and . - */ -mxEditor.prototype.createSession = function () -{ - // Routes any change events from the session - // through the editor and dispatches them as - // a session event. - var sessionChanged = mxUtils.bind(this, function(session) - { - this.fireEvent(new mxEventObject(mxEvent.SESSION, 'session', session)); - }); - - return this.connect(this.urlInit, this.urlPoll, - this.urlNotify, sessionChanged); -}; - -/** - * Function: configure - * - * Configures the editor using the specified node. To load the - * configuration from a given URL the following code can be used to obtain - * the XML node. - * - * (code) - * var node = mxUtils.load(url).getDocumentElement(); - * (end) - * - * Parameters: - * - * node - XML node that contains the configuration. - */ -mxEditor.prototype.configure = function (node) -{ - if (node != null) - { - // Creates a decoder for the XML data - // and uses it to configure the editor - var dec = new mxCodec(node.ownerDocument); - dec.decode(node, this); - - // Resets the counters, modified state and - // command history - this.resetHistory(); - } -}; - -/** - * Function: resetFirstTime - * - * Resets the cookie that is used to remember if the editor has already - * been used. - */ -mxEditor.prototype.resetFirstTime = function () -{ - document.cookie = - 'mxgraph=seen; expires=Fri, 27 Jul 2001 02:47:11 UTC; path=/'; -}; - -/** - * Function: resetHistory - * - * Resets the command history, modified state and counters. - */ -mxEditor.prototype.resetHistory = function () -{ - this.lastSnapshot = new Date().getTime(); - this.undoManager.clear(); - this.ignoredChanges = 0; - this.setModified(false); -}; - -/** - * Function: addAction - * - * Binds the specified actionname to the specified function. - * - * Parameters: - * - * actionname - String that specifies the name of the action - * to be added. - * funct - Function that implements the new action. The first - * argument of the function is the editor it is used - * with, the second argument is the cell it operates - * upon. - * - * Example: - * (code) - * editor.addAction('test', function(editor, cell) - * { - * mxUtils.alert("test "+cell); - * }); - * (end) - */ -mxEditor.prototype.addAction = function (actionname, funct) -{ - this.actions[actionname] = funct; -}; - -/** - * Function: execute - * - * Executes the function with the given name in passing the - * editor instance and given cell as the first and second argument. All - * additional arguments are passed to the action as well. This method - * contains a try-catch block and displays an error message if an action - * causes an exception. The exception is re-thrown after the error - * message was displayed. - * - * Example: - * - * (code) - * editor.execute("showProperties", cell); - * (end) - */ -mxEditor.prototype.execute = function (actionname, cell, evt) -{ - var action = this.actions[actionname]; - - if (action != null) - { - try - { - // Creates the array of arguments by replacing the actionname - // with the editor instance in the args of this function - var args = arguments; - args[0] = this; - - // Invokes the function on the editor using the args - action.apply(this, args); - } - catch (e) - { - mxUtils.error('Cannot execute ' + actionname + - ': ' + e.message, 280, true); - - throw e; - } - } - else - { - mxUtils.error('Cannot find action '+actionname, 280, true); - } -}; - -/** - * Function: addTemplate - * - * Adds the specified template under the given name in . - */ -mxEditor.prototype.addTemplate = function (name, template) -{ - this.templates[name] = template; -}; - -/** - * Function: getTemplate - * - * Returns the template for the given name. - */ -mxEditor.prototype.getTemplate = function (name) -{ - return this.templates[name]; -}; - -/** - * Function: createGraph - * - * Creates the for the editor. The graph is created with no - * container and is initialized from . - */ -mxEditor.prototype.createGraph = function () -{ - var graph = new mxGraph(null, null, this.graphRenderHint); - - // Enables rubberband, tooltips, panning - graph.setTooltips(true); - graph.setPanning(true); - - // Overrides the dblclick method on the graph to - // invoke the dblClickAction for a cell and reset - // the selection tool in the toolbar - this.installDblClickHandler(graph); - - // Installs the command history - this.installUndoHandler(graph); - - // Installs the handlers for the root event - this.installDrillHandler(graph); - - // Installs the handler for validation - this.installChangeHandler(graph); - - // Installs the handler for calling the - // insert function and consume the - // event if an insert function is defined - this.installInsertHandler(graph); - - // Redirects the function for creating the - // popupmenu items - graph.panningHandler.factoryMethod = - mxUtils.bind(this, function(menu, cell, evt) - { - return this.createPopupMenu(menu, cell, evt); - }); - - // Redirects the function for creating - // new connections in the diagram - graph.connectionHandler.factoryMethod = - mxUtils.bind(this, function(source, target) - { - return this.createEdge(source, target); - }); - - // Maintains swimlanes and installs autolayout - this.createSwimlaneManager(graph); - this.createLayoutManager(graph); - - return graph; -}; - -/** - * Function: createSwimlaneManager - * - * Sets the graph's container using . - */ -mxEditor.prototype.createSwimlaneManager = function (graph) -{ - var swimlaneMgr = new mxSwimlaneManager(graph, false); - - swimlaneMgr.isHorizontal = mxUtils.bind(this, function() - { - return this.horizontalFlow; - }); - - swimlaneMgr.isEnabled = mxUtils.bind(this, function() - { - return this.maintainSwimlanes; - }); - - return swimlaneMgr; -}; - -/** - * Function: createLayoutManager - * - * Creates a layout manager for the swimlane and diagram layouts, that - * is, the locally defined inter- and intraswimlane layouts. - */ -mxEditor.prototype.createLayoutManager = function (graph) -{ - var layoutMgr = new mxLayoutManager(graph); - - var self = this; // closure - layoutMgr.getLayout = function(cell) - { - var layout = null; - var model = self.graph.getModel(); - - if (model.getParent(cell) != null) - { - // Executes the swimlane layout if a child of - // a swimlane has been changed. The layout is - // lazy created in createSwimlaneLayout. - if (self.layoutSwimlanes && - graph.isSwimlane(cell)) - { - if (self.swimlaneLayout == null) - { - self.swimlaneLayout = self.createSwimlaneLayout(); - } - - layout = self.swimlaneLayout; - } - - // Executes the diagram layout if the modified - // cell is a top-level cell. The layout is - // lazy created in createDiagramLayout. - else if (self.layoutDiagram && - (graph.isValidRoot(cell) || - model.getParent(model.getParent(cell)) == null)) - { - if (self.diagramLayout == null) - { - self.diagramLayout = self.createDiagramLayout(); - } - - layout = self.diagramLayout; - } - } - - return layout; - }; - - return layoutMgr; -}; - -/** - * Function: setGraphContainer - * - * Sets the graph's container using . - */ -mxEditor.prototype.setGraphContainer = function (container) -{ - if (this.graph.container == null) - { - // Creates the graph instance inside the given container and render hint - //this.graph = new mxGraph(container, null, this.graphRenderHint); - this.graph.init(container); - - // Install rubberband selection as the last - // action handler in the chain - this.rubberband = new mxRubberband(this.graph); - - // Disables the context menu - if (this.disableContextMenu) - { - mxEvent.disableContextMenu(container); - } - - // Workaround for stylesheet directives in IE - if (mxClient.IS_QUIRKS) - { - new mxDivResizer(container); - } - } -}; - -/** - * Function: installDblClickHandler - * - * Overrides to invoke - * on a cell and reset the selection tool in the toolbar. - */ -mxEditor.prototype.installDblClickHandler = function (graph) -{ - // Installs a listener for double click events - graph.addListener(mxEvent.DOUBLE_CLICK, - mxUtils.bind(this, function(sender, evt) - { - var cell = evt.getProperty('cell'); - - if (cell != null && - graph.isEnabled() && - this.dblClickAction != null) - { - this.execute(this.dblClickAction, cell); - evt.consume(); - } - }) - ); -}; - -/** - * Function: installUndoHandler - * - * Adds the to the graph model and the view. - */ -mxEditor.prototype.installUndoHandler = function (graph) -{ - var listener = mxUtils.bind(this, function(sender, evt) - { - var edit = evt.getProperty('edit'); - this.undoManager.undoableEditHappened(edit); - }); - - graph.getModel().addListener(mxEvent.UNDO, listener); - graph.getView().addListener(mxEvent.UNDO, listener); - - // Keeps the selection state in sync - var undoHandler = function(sender, evt) - { - var changes = evt.getProperty('edit').changes; - graph.setSelectionCells(graph.getSelectionCellsForChanges(changes)); - }; - - this.undoManager.addListener(mxEvent.UNDO, undoHandler); - this.undoManager.addListener(mxEvent.REDO, undoHandler); -}; - -/** - * Function: installDrillHandler - * - * Installs listeners for dispatching the event. - */ -mxEditor.prototype.installDrillHandler = function (graph) -{ - var listener = mxUtils.bind(this, function(sender) - { - this.fireEvent(new mxEventObject(mxEvent.ROOT)); - }); - - graph.getView().addListener(mxEvent.DOWN, listener); - graph.getView().addListener(mxEvent.UP, listener); -}; - -/** - * Function: installChangeHandler - * - * Installs the listeners required to automatically validate - * the graph. On each change of the root, this implementation - * fires a event. - */ -mxEditor.prototype.installChangeHandler = function (graph) -{ - var listener = mxUtils.bind(this, function(sender, evt) - { - // Updates the modified state - this.setModified(true); - - // Automatically validates the graph - // after each change - if (this.validating == true) - { - graph.validateGraph(); - } - - // Checks if the root has been changed - var changes = evt.getProperty('edit').changes; - - for (var i = 0; i < changes.length; i++) - { - var change = changes[i]; - - if (change instanceof mxRootChange || - (change instanceof mxValueChange && - change.cell == this.graph.model.root) || - (change instanceof mxCellAttributeChange && - change.cell == this.graph.model.root)) - { - this.fireEvent(new mxEventObject(mxEvent.ROOT)); - break; - } - } - }); - - graph.getModel().addListener(mxEvent.CHANGE, listener); -}; - -/** - * Function: installInsertHandler - * - * Installs the handler for invoking if - * one is defined. - */ -mxEditor.prototype.installInsertHandler = function (graph) -{ - var self = this; // closure - var insertHandler = - { - mouseDown: function(sender, me) - { - if (self.insertFunction != null && - !me.isPopupTrigger() && - (self.forcedInserting || - me.getState() == null)) - { - self.graph.clearSelection(); - self.insertFunction(me.getEvent(), me.getCell()); - - // Consumes the rest of the events - // for this gesture (down, move, up) - this.isActive = true; - me.consume(); - } - }, - - mouseMove: function(sender, me) - { - if (this.isActive) - { - me.consume(); - } - }, - - mouseUp: function(sender, me) - { - if (this.isActive) - { - this.isActive = false; - me.consume(); - } - } - }; - - graph.addMouseListener(insertHandler); -}; - -/** - * Function: createDiagramLayout - * - * Creates the layout instance used to layout the - * swimlanes in the diagram. - */ -mxEditor.prototype.createDiagramLayout = function () -{ - var gs = this.graph.gridSize; - var layout = new mxStackLayout(this.graph, !this.horizontalFlow, - this.swimlaneSpacing, 2*gs, 2*gs); - - // Overrides isIgnored to only take into account swimlanes - layout.isVertexIgnored = function(cell) - { - return !layout.graph.isSwimlane(cell); - }; - - return layout; -}; - -/** - * Function: createSwimlaneLayout - * - * Creates the layout instance used to layout the - * children of each swimlane. - */ -mxEditor.prototype.createSwimlaneLayout = function () -{ - return new mxCompactTreeLayout(this.graph, this.horizontalFlow); -}; - -/** - * Function: createToolbar - * - * Creates the with no container. - */ -mxEditor.prototype.createToolbar = function () -{ - return new mxDefaultToolbar(null, this); -}; - -/** - * Function: setToolbarContainer - * - * Initializes the toolbar for the given container. - */ -mxEditor.prototype.setToolbarContainer = function (container) -{ - this.toolbar.init(container); - - // Workaround for stylesheet directives in IE - if (mxClient.IS_QUIRKS) - { - new mxDivResizer(container); - } -}; - -/** - * Function: setStatusContainer - * - * Creates the using the specified container. - * - * This implementation adds listeners in the editor to - * display the last saved time and the current filename - * in the status bar. - * - * Parameters: - * - * container - DOM node that will contain the statusbar. - */ -mxEditor.prototype.setStatusContainer = function (container) -{ - if (this.status == null) - { - this.status = container; - - // Prints the last saved time in the status bar - // when files are saved - this.addListener(mxEvent.SAVE, mxUtils.bind(this, function() - { - var tstamp = new Date().toLocaleString(); - this.setStatus((mxResources.get(this.lastSavedResource) || - this.lastSavedResource)+': '+tstamp); - })); - - // Updates the statusbar to display the filename - // when new files are opened - this.addListener(mxEvent.OPEN, mxUtils.bind(this, function() - { - this.setStatus((mxResources.get(this.currentFileResource) || - this.currentFileResource)+': '+this.filename); - })); - - // Workaround for stylesheet directives in IE - if (mxClient.IS_QUIRKS) - { - new mxDivResizer(container); - } - } -}; - -/** - * Function: setStatus - * - * Display the specified message in the status bar. - * - * Parameters: - * - * message - String the specified the message to - * be displayed. - */ -mxEditor.prototype.setStatus = function (message) -{ - if (this.status != null && message != null) - { - this.status.innerHTML = message; - } -}; - -/** - * Function: setTitleContainer - * - * Creates a listener to update the inner HTML of the - * specified DOM node with the value of . - * - * Parameters: - * - * container - DOM node that will contain the title. - */ -mxEditor.prototype.setTitleContainer = function (container) -{ - this.addListener(mxEvent.ROOT, mxUtils.bind(this, function(sender) - { - container.innerHTML = this.getTitle(); - })); - - // Workaround for stylesheet directives in IE - if (mxClient.IS_QUIRKS) - { - new mxDivResizer(container); - } -}; - -/** - * Function: treeLayout - * - * Executes a vertical or horizontal compact tree layout - * using the specified cell as an argument. The cell may - * either be a group or the root of a tree. - * - * Parameters: - * - * cell - to use in the compact tree layout. - * horizontal - Optional boolean to specify the tree's - * orientation. Default is true. - */ -mxEditor.prototype.treeLayout = function (cell, horizontal) -{ - if (cell != null) - { - var layout = new mxCompactTreeLayout(this.graph, horizontal); - layout.execute(cell); - } -}; - -/** - * Function: getTitle - * - * Returns the string value for the current root of the - * diagram. - */ -mxEditor.prototype.getTitle = function () -{ - var title = ''; - var graph = this.graph; - var cell = graph.getCurrentRoot(); - - while (cell != null && - graph.getModel().getParent( - graph.getModel().getParent(cell)) != null) - { - // Append each label of a valid root - if (graph.isValidRoot(cell)) - { - title = ' > ' + - graph.convertValueToString(cell) + title; - } - - cell = graph.getModel().getParent(cell); - } - - var prefix = this.getRootTitle(); - - return prefix + title; -}; - -/** - * Function: getRootTitle - * - * Returns the string value of the root cell in - * . - */ -mxEditor.prototype.getRootTitle = function () -{ - var root = this.graph.getModel().getRoot(); - return this.graph.convertValueToString(root); -}; - -/** - * Function: undo - * - * Undo the last change in . - */ -mxEditor.prototype.undo = function () -{ - this.undoManager.undo(); -}; - -/** - * Function: redo - * - * Redo the last change in . - */ -mxEditor.prototype.redo = function () -{ - this.undoManager.redo(); -}; - -/** - * Function: groupCells - * - * Invokes to create a new group cell and the invokes - * , using the grid size of the graph as the spacing - * in the group's content area. - */ -mxEditor.prototype.groupCells = function () -{ - var border = (this.groupBorderSize != null) ? - this.groupBorderSize : - this.graph.gridSize; - return this.graph.groupCells(this.createGroup(), border); -}; - -/** - * Function: createGroup - * - * Creates and returns a clone of to be used - * as a new group cell in . - */ -mxEditor.prototype.createGroup = function () -{ - var model = this.graph.getModel(); - - return model.cloneCell(this.defaultGroup); -}; - -/** - * Function: open - * - * Opens the specified file synchronously and parses it using - * . It updates and fires an -event after - * the file has been opened. Exceptions should be handled as follows: - * - * (code) - * try - * { - * editor.open(filename); - * } - * catch (e) - * { - * mxUtils.error('Cannot open ' + filename + - * ': ' + e.message, 280, true); - * } - * (end) - * - * Parameters: - * - * filename - URL of the file to be opened. - */ -mxEditor.prototype.open = function (filename) -{ - if (filename != null) - { - var xml = mxUtils.load(filename).getXml(); - this.readGraphModel(xml.documentElement); - this.filename = filename; - - this.fireEvent(new mxEventObject(mxEvent.OPEN, 'filename', filename)); - } -}; - -/** - * Function: readGraphModel - * - * Reads the specified XML node into the existing graph model and resets - * the command history and modified state. - */ -mxEditor.prototype.readGraphModel = function (node) -{ - var dec = new mxCodec(node.ownerDocument); - dec.decode(node, this.graph.getModel()); - this.resetHistory(); -}; - -/** - * Function: save - * - * Posts the string returned by to the given URL or the - * URL returned by . The actual posting is carried out by - * . If the URL is null then the resulting XML will be - * displayed using . Exceptions should be handled as - * follows: - * - * (code) - * try - * { - * editor.save(); - * } - * catch (e) - * { - * mxUtils.error('Cannot save : ' + e.message, 280, true); - * } - * (end) - */ -mxEditor.prototype.save = function (url, linefeed) -{ - // Gets the URL to post the data to - url = url || this.getUrlPost(); - - // Posts the data if the URL is not empty - if (url != null && url.length > 0) - { - var data = this.writeGraphModel(linefeed); - this.postDiagram(url, data); - - // Resets the modified flag - this.setModified(false); - } - - // Dispatches a save event - this.fireEvent(new mxEventObject(mxEvent.SAVE, 'url', url)); -}; - -/** - * Function: postDiagram - * - * Hook for subclassers to override the posting of a diagram - * represented by the given node to the given URL. This fires - * an asynchronous event if the diagram has been posted. - * - * Example: - * - * To replace the diagram with the diagram in the response, use the - * following code. - * - * (code) - * editor.addListener(mxEvent.POST, function(sender, evt) - * { - * // Process response (replace diagram) - * var req = evt.getProperty('request'); - * var root = req.getDocumentElement(); - * editor.graph.readGraphModel(root) - * }); - * (end) - */ -mxEditor.prototype.postDiagram = function (url, data) -{ - if (this.escapePostData) - { - data = encodeURIComponent(data); - } - - mxUtils.post(url, this.postParameterName+'='+data, - mxUtils.bind(this, function(req) - { - this.fireEvent(new mxEventObject(mxEvent.POST, - 'request', req, 'url', url, 'data', data)); - }) - ); -}; - -/** - * Function: writeGraphModel - * - * Hook to create the string representation of the diagram. The default - * implementation uses an to encode the graph model as - * follows: - * - * (code) - * var enc = new mxCodec(); - * var node = enc.encode(this.graph.getModel()); - * return mxUtils.getXml(node, this.linefeed); - * (end) - * - * Parameters: - * - * linefeed - Optional character to be used as the linefeed. Default is - * . - */ -mxEditor.prototype.writeGraphModel = function (linefeed) -{ - linefeed = (linefeed != null) ? linefeed : this.linefeed; - var enc = new mxCodec(); - var node = enc.encode(this.graph.getModel()); - - return mxUtils.getXml(node, linefeed); -}; - -/** - * Function: getUrlPost - * - * Returns the URL to post the diagram to. This is used - * in . The default implementation returns , - * adding ?draft=true. - */ -mxEditor.prototype.getUrlPost = function () -{ - return this.urlPost; -}; - -/** - * Function: getUrlImage - * - * Returns the URL to create the image with. This is typically - * the URL of a backend which accepts an XML representation - * of a graph view to create an image. The function is used - * in the image action to create an image. This implementation - * returns . - */ -mxEditor.prototype.getUrlImage = function () -{ - return this.urlImage; -}; - -/** - * Function: connect - * - * Creates and returns a session for the specified parameters, installing - * the onChange function as a change listener for the session. - */ -mxEditor.prototype.connect = function (urlInit, urlPoll, urlNotify, onChange) -{ - var session = null; - - if (!mxClient.IS_LOCAL) - { - session = new mxSession(this.graph.getModel(), - urlInit, urlPoll, urlNotify); - - // Resets the undo history if the session was initialized which is the - // case if the message carries a namespace to be used for new IDs. - session.addListener(mxEvent.RECEIVE, - mxUtils.bind(this, function(sender, evt) - { - var node = evt.getProperty('node'); - - if (node.getAttribute('namespace') != null) - { - this.resetHistory(); - } - }) - ); - - // Installs the listener for all events - // that signal a change of the session - session.addListener(mxEvent.DISCONNECT, onChange); - session.addListener(mxEvent.CONNECT, onChange); - session.addListener(mxEvent.NOTIFY, onChange); - session.addListener(mxEvent.GET, onChange); - session.start(); - } - - return session; -}; - -/** - * Function: swapStyles - * - * Swaps the styles for the given names in the graph's - * stylesheet and refreshes the graph. - */ -mxEditor.prototype.swapStyles = function (first, second) -{ - var style = this.graph.getStylesheet().styles[second]; - this.graph.getView().getStylesheet().putCellStyle( - second, this.graph.getStylesheet().styles[first]); - this.graph.getStylesheet().putCellStyle(first, style); - this.graph.refresh(); -}; - -/** - * Function: showProperties - * - * Creates and shows the properties dialog for the given - * cell. The content area of the dialog is created using - * . - */ -mxEditor.prototype.showProperties = function (cell) -{ - cell = cell || this.graph.getSelectionCell(); - - // Uses the root node for the properties dialog - // if not cell was passed in and no cell is - // selected - if (cell == null) - { - cell = this.graph.getCurrentRoot(); - - if (cell == null) - { - cell = this.graph.getModel().getRoot(); - } - } - - if (cell != null) - { - // Makes sure there is no in-place editor in the - // graph and computes the location of the dialog - this.graph.stopEditing(true); - - var offset = mxUtils.getOffset(this.graph.container); - var x = offset.x+10; - var y = offset.y; - - // Avoids moving the dialog if it is alredy open - if (this.properties != null && !this.movePropertiesDialog) - { - x = this.properties.getX(); - y = this.properties.getY(); - } - - // Places the dialog near the cell for which it - // displays the properties - else - { - var bounds = this.graph.getCellBounds(cell); - - if (bounds != null) - { - x += bounds.x+Math.min(200, bounds.width); - y += bounds.y; - } - } - - // Hides the existing properties dialog and creates a new one with the - // contents created in the hook method - this.hideProperties(); - var node = this.createProperties(cell); - - if (node != null) - { - // Displays the contents in a window and stores a reference to the - // window for later hiding of the window - this.properties = new mxWindow(mxResources.get(this.propertiesResource) || - this.propertiesResource, node, x, y, this.propertiesWidth, this.propertiesHeight, false); - this.properties.setVisible(true); - } - } -}; - -/** - * Function: isPropertiesVisible - * - * Returns true if the properties dialog is currently visible. - */ -mxEditor.prototype.isPropertiesVisible = function () -{ - return this.properties != null; -}; - -/** - * Function: createProperties - * - * Creates and returns the DOM node that represents the contents - * of the properties dialog for the given cell. This implementation - * works for user objects that are XML nodes and display all the - * node attributes in a form. - */ -mxEditor.prototype.createProperties = function (cell) -{ - var model = this.graph.getModel(); - var value = model.getValue(cell); - - if (mxUtils.isNode(value)) - { - // Creates a form for the user object inside - // the cell - var form = new mxForm('properties'); - - // Adds a readonly field for the cell id - var id = form.addText('ID', cell.getId()); - id.setAttribute('readonly', 'true'); - - var geo = null; - var yField = null; - var xField = null; - var widthField = null; - var heightField = null; - - // Adds fields for the location and size - if (model.isVertex(cell)) - { - geo = model.getGeometry(cell); - - if (geo != null) - { - yField = form.addText('top', geo.y); - xField = form.addText('left', geo.x); - widthField = form.addText('width', geo.width); - heightField = form.addText('height', geo.height); - } - } - - // Adds a field for the cell style - var tmp = model.getStyle(cell); - var style = form.addText('Style', tmp || ''); - - // Creates textareas for each attribute of the - // user object within the cell - var attrs = value.attributes; - var texts = []; - - for (var i = 0; i < attrs.length; i++) - { - // Creates a textarea with more lines for - // the cell label - var val = attrs[i].nodeValue; - texts[i] = form.addTextarea(attrs[i].nodeName, val, - (attrs[i].nodeName == 'label') ? 4 : 2); - } - - // Adds an OK and Cancel button to the dialog - // contents and implements the respective - // actions below - - // Defines the function to be executed when the - // OK button is pressed in the dialog - var okFunction = mxUtils.bind(this, function() - { - // Hides the dialog - this.hideProperties(); - - // Supports undo for the changes on the underlying - // XML structure / XML node attribute changes. - model.beginUpdate(); - try - { - if (geo != null) - { - geo = geo.clone(); - - geo.x = parseFloat(xField.value); - geo.y = parseFloat(yField.value); - geo.width = parseFloat(widthField.value); - geo.height = parseFloat(heightField.value); - - model.setGeometry(cell, geo); - } - - // Applies the style - if (style.value.length > 0) - { - model.setStyle(cell, style.value); - } - else - { - model.setStyle(cell, null); - } - - // Creates an undoable change for each - // attribute and executes it using the - // model, which will also make the change - // part of the current transaction - for (var i=0; i. The - * default width of the window is 200 pixels, the y-coordinate of the location - * can be specifies in and the x-coordinate is right aligned with a - * 20 pixel offset from the right border. To change the location of the tasks - * window, the following code can be used: - * - * (code) - * var oldShowTasks = mxEditor.prototype.showTasks; - * mxEditor.prototype.showTasks = function() - * { - * oldShowTasks.apply(this, arguments); // "supercall" - * - * if (this.tasks != null) - * { - * this.tasks.setLocation(10, 10); - * } - * }; - * (end) - */ -mxEditor.prototype.showTasks = function () -{ - if (this.tasks == null) - { - var div = document.createElement('div'); - div.style.padding = '4px'; - div.style.paddingLeft = '20px'; - var w = document.body.clientWidth; - var wnd = new mxWindow( - mxResources.get(this.tasksResource) || - this.tasksResource, - div, w - 220, this.tasksTop, 200); - wnd.setClosable(true); - wnd.destroyOnClose = false; - - // Installs a function to update the contents - // of the tasks window on every change of the - // model, selection or root. - var funct = mxUtils.bind(this, function(sender) - { - mxEvent.release(div); - div.innerHTML = ''; - this.createTasks(div); - }); - - this.graph.getModel().addListener(mxEvent.CHANGE, funct); - this.graph.getSelectionModel().addListener(mxEvent.CHANGE, funct); - this.graph.addListener(mxEvent.ROOT, funct); - - // Assigns the icon to the tasks window - if (this.tasksWindowImage != null) - { - wnd.setImage(this.tasksWindowImage); - } - - this.tasks = wnd; - this.createTasks(div); - } - - this.tasks.setVisible(true); -}; - -/** - * Function: refreshTasks - * - * Updates the contents of the tasks window using . - */ -mxEditor.prototype.refreshTasks = function (div) -{ - if (this.tasks != null) - { - var div = this.tasks.content; - mxEvent.release(div); - div.innerHTML = ''; - this.createTasks(div); - } -}; - -/** - * Function: createTasks - * - * Updates the contents of the given DOM node to - * display the tasks associated with the current - * editor state. This is invoked whenever there - * is a possible change of state in the editor. - * Default implementation is empty. - */ -mxEditor.prototype.createTasks = function (div) -{ - // override -}; - -/** - * Function: showHelp - * - * Shows the help window. If the help window does not exist - * then it is created using an iframe pointing to the resource - * for the urlHelp key or if the resource - * is undefined. - */ -mxEditor.prototype.showHelp = function (tasks) -{ - if (this.help == null) - { - var frame = document.createElement('iframe'); - frame.setAttribute('src', mxResources.get('urlHelp') || this.urlHelp); - frame.setAttribute('height', '100%'); - frame.setAttribute('width', '100%'); - frame.setAttribute('frameBorder', '0'); - frame.style.backgroundColor = 'white'; - - var w = document.body.clientWidth; - var h = (document.body.clientHeight || document.documentElement.clientHeight); - - var wnd = new mxWindow(mxResources.get(this.helpResource) || this.helpResource, - frame, (w-this.helpWidth)/2, (h-this.helpHeight)/3, this.helpWidth, this.helpHeight); - wnd.setMaximizable(true); - wnd.setClosable(true); - wnd.destroyOnClose = false; - wnd.setResizable(true); - - // Assigns the icon to the help window - if (this.helpWindowImage != null) - { - wnd.setImage(this.helpWindowImage); - } - - // Workaround for ignored iframe height 100% in FF - if (mxClient.IS_NS) - { - var handler = function(sender) - { - var h = wnd.div.offsetHeight; - frame.setAttribute('height', (h-26)+'px'); - }; - - wnd.addListener(mxEvent.RESIZE_END, handler); - wnd.addListener(mxEvent.MAXIMIZE, handler); - wnd.addListener(mxEvent.NORMALIZE, handler); - wnd.addListener(mxEvent.SHOW, handler); - } - - this.help = wnd; - } - - this.help.setVisible(true); -}; - -/** - * Function: showOutline - * - * Shows the outline window. If the window does not exist, then it is - * created using an . - */ -mxEditor.prototype.showOutline = function () -{ - var create = this.outline == null; - - if (create) - { - var div = document.createElement('div'); - div.style.overflow = 'hidden'; - div.style.width = '100%'; - div.style.height = '100%'; - div.style.background = 'white'; - div.style.cursor = 'move'; - - var wnd = new mxWindow( - mxResources.get(this.outlineResource) || - this.outlineResource, - div, 600, 480, 200, 200, false); - - // Creates the outline in the specified div - // and links it to the existing graph - var outline = new mxOutline(this.graph, div); - wnd.setClosable(true); - wnd.setResizable(true); - wnd.destroyOnClose = false; - - wnd.addListener(mxEvent.RESIZE_END, function() - { - outline.update(); - }); - - this.outline = wnd; - this.outline.outline = outline; - } - - // Finally shows the outline - this.outline.setVisible(true); - this.outline.outline.update(true); -}; - -/** - * Function: setMode - * - * Puts the graph into the specified mode. The following modenames are - * supported: - * - * select - Selects using the left mouse button, new connections - * are disabled. - * connect - Selects using the left mouse button or creates new - * connections if mouse over cell hotspot. See . - * pan - Pans using the left mouse button, new connections are disabled. - */ -mxEditor.prototype.setMode = function(modename) -{ - if (modename == 'select') - { - this.graph.panningHandler.useLeftButtonForPanning = false; - this.graph.setConnectable(false); - } - else if (modename == 'connect') - { - this.graph.panningHandler.useLeftButtonForPanning = false; - this.graph.setConnectable(true); - } - else if (modename == 'pan') - { - this.graph.panningHandler.useLeftButtonForPanning = true; - this.graph.setConnectable(false); - } -}; - -/** - * Function: createPopupMenu - * - * Uses to create the menu in the graph's - * panning handler. The redirection is setup in - * . - */ -mxEditor.prototype.createPopupMenu = function (menu, cell, evt) -{ - this.popupHandler.createMenu(this, menu, cell, evt); -}; - -/** - * Function: createEdge - * - * Uses as the prototype for creating new edges - * in the connection handler of the graph. The style of the - * edge will be overridden with the value returned by - * . - */ -mxEditor.prototype.createEdge = function (source, target) -{ - // Clones the defaultedge prototype - var e = null; - - if (this.defaultEdge != null) - { - var model = this.graph.getModel(); - e = model.cloneCell(this.defaultEdge); - } - else - { - e = new mxCell(''); - e.setEdge(true); - - var geo = new mxGeometry(); - geo.relative = true; - e.setGeometry(geo); - } - - // Overrides the edge style - var style = this.getEdgeStyle(); - - if (style != null) - { - e.setStyle(style); - } - - return e; -}; - -/** - * Function: getEdgeStyle - * - * Returns a string identifying the style of new edges. - * The function is used in when new edges - * are created in the graph. - */ -mxEditor.prototype.getEdgeStyle = function () -{ - return this.defaultEdgeStyle; -}; - -/** - * Function: consumeCycleAttribute - * - * Returns the next attribute in - * or null, if not attribute should be used in the - * specified cell. - */ -mxEditor.prototype.consumeCycleAttribute = function (cell) -{ - return (this.cycleAttributeValues != null && - this.cycleAttributeValues.length > 0 && - this.graph.isSwimlane(cell)) ? - this.cycleAttributeValues[this.cycleAttributeIndex++ % - this.cycleAttributeValues.length] : null; -}; - -/** - * Function: cycleAttribute - * - * Uses the returned value from - * as the value for the key in - * the given cell's style. - */ -mxEditor.prototype.cycleAttribute = function (cell) -{ - if (this.cycleAttributeName != null) - { - var value = this.consumeCycleAttribute(cell); - - if (value != null) - { - cell.setStyle(cell.getStyle()+';'+ - this.cycleAttributeName+'='+value); - } - } -}; - -/** - * Function: addVertex - * - * Adds the given vertex as a child of parent at the specified - * x and y coordinate and fires an event. - */ -mxEditor.prototype.addVertex = function (parent, vertex, x, y) -{ - var model = this.graph.getModel(); - - while (parent != null && !this.graph.isValidDropTarget(parent)) - { - parent = model.getParent(parent); - } - - parent = (parent != null) ? parent : this.graph.getSwimlaneAt(x, y); - var scale = this.graph.getView().scale; - - var geo = model.getGeometry(vertex); - var pgeo = model.getGeometry(parent); - - if (this.graph.isSwimlane(vertex) && - !this.graph.swimlaneNesting) - { - parent = null; - } - else if (parent == null && this.swimlaneRequired) - { - return null; - } - else if (parent != null && pgeo != null) - { - // Keeps vertex inside parent - var state = this.graph.getView().getState(parent); - - if (state != null) - { - x -= state.origin.x * scale; - y -= state.origin.y * scale; - - if (this.graph.isConstrainedMoving) - { - var width = geo.width; - var height = geo.height; - var tmp = state.x+state.width; - - if (x+width > tmp) - { - x -= x+width - tmp; - } - - tmp = state.y+state.height; - - if (y+height > tmp) - { - y -= y+height - tmp; - } - } - } - else if (pgeo != null) - { - x -= pgeo.x*scale; - y -= pgeo.y*scale; - } - } - - geo = geo.clone(); - geo.x = this.graph.snap(x / scale - - this.graph.getView().translate.x - - this.graph.gridSize/2); - geo.y = this.graph.snap(y / scale - - this.graph.getView().translate.y - - this.graph.gridSize/2); - vertex.setGeometry(geo); - - if (parent == null) - { - parent = this.graph.getDefaultParent(); - } - - this.cycleAttribute(vertex); - this.fireEvent(new mxEventObject(mxEvent.BEFORE_ADD_VERTEX, - 'vertex', vertex, 'parent', parent)); - - model.beginUpdate(); - try - { - vertex = this.graph.addCell(vertex, parent); - - if (vertex != null) - { - this.graph.constrainChild(vertex); - - this.fireEvent(new mxEventObject(mxEvent.ADD_VERTEX, 'vertex', vertex)); - } - } - finally - { - model.endUpdate(); - } - - if (vertex != null) - { - this.graph.setSelectionCell(vertex); - this.graph.scrollCellToVisible(vertex); - this.fireEvent(new mxEventObject(mxEvent.AFTER_ADD_VERTEX, 'vertex', vertex)); - } - - return vertex; -}; - -/** - * Function: destroy - * - * Removes the editor and all its associated resources. This does not - * normally need to be called, it is called automatically when the window - * unloads. - */ -mxEditor.prototype.destroy = function () -{ - if (!this.destroyed) - { - this.destroyed = true; - - if (this.tasks != null) - { - this.tasks.destroy(); - } - - if (this.outline != null) - { - this.outline.destroy(); - } - - if (this.properties != null) - { - this.properties.destroy(); - } - - if (this.keyHandler != null) - { - this.keyHandler.destroy(); - } - - if (this.rubberband != null) - { - this.rubberband.destroy(); - } - - if (this.toolbar != null) - { - this.toolbar.destroy(); - } - - if (this.graph != null) - { - this.graph.destroy(); - } - - this.status = null; - this.templates = null; - } -}; diff --git a/src/js/handler/mxCellHighlight.js b/src/js/handler/mxCellHighlight.js deleted file mode 100644 index f967f00..0000000 --- a/src/js/handler/mxCellHighlight.js +++ /dev/null @@ -1,271 +0,0 @@ -/** - * $Id: mxCellHighlight.js,v 1.25 2012-09-27 14:43:40 boris Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxCellHighlight - * - * A helper class to highlight cells. Here is an example for a given cell. - * - * (code) - * var highlight = new mxCellHighlight(graph, '#ff0000', 2); - * highlight.highlight(graph.view.getState(cell))); - * (end) - * - * Constructor: mxCellHighlight - * - * Constructs a cell highlight. - */ -function mxCellHighlight(graph, highlightColor, strokeWidth) -{ - if (graph != null) - { - this.graph = graph; - this.highlightColor = (highlightColor != null) ? highlightColor : mxConstants.DEFAULT_VALID_COLOR; - this.strokeWidth = (strokeWidth != null) ? strokeWidth : mxConstants.HIGHLIGHT_STROKEWIDTH; - - // Updates the marker if the graph changes - this.repaintHandler = mxUtils.bind(this, function() - { - this.repaint(); - }); - - this.graph.getView().addListener(mxEvent.SCALE, this.repaintHandler); - this.graph.getView().addListener(mxEvent.TRANSLATE, this.repaintHandler); - this.graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, this.repaintHandler); - this.graph.getModel().addListener(mxEvent.CHANGE, this.repaintHandler); - - // Hides the marker if the current root changes - this.resetHandler = mxUtils.bind(this, function() - { - this.hide(); - }); - - this.graph.getView().addListener(mxEvent.DOWN, this.resetHandler); - this.graph.getView().addListener(mxEvent.UP, this.resetHandler); - } -}; - -/** - * Variable: keepOnTop - * - * Specifies if the highlights should appear on top of everything - * else in the overlay pane. Default is false. - */ -mxCellHighlight.prototype.keepOnTop = false; - -/** - * Variable: graph - * - * Reference to the enclosing . - */ -mxCellHighlight.prototype.graph = true; - -/** - * Variable: state - * - * Reference to the . - */ -mxCellHighlight.prototype.state = null; - -/** - * Variable: spacing - * - * Specifies the spacing between the highlight for vertices and the vertex. - * Default is 2. - */ -mxCellHighlight.prototype.spacing = 2; - -/** - * Variable: resetHandler - * - * Holds the handler that automatically invokes reset if the highlight - * should be hidden. - */ -mxCellHighlight.prototype.resetHandler = null; - -/** - * Function: setHighlightColor - * - * Sets the color of the rectangle used to highlight drop targets. - * - * Parameters: - * - * color - String that represents the new highlight color. - */ -mxCellHighlight.prototype.setHighlightColor = function(color) -{ - this.highlightColor = color; - - if (this.shape != null) - { - if (this.shape.dialect == mxConstants.DIALECT_SVG) - { - this.shape.innerNode.setAttribute('stroke', color); - } - else if (this.shape.dialect == mxConstants.DIALECT_VML) - { - this.shape.node.strokecolor = color; - } - } -}; - -/** - * Function: drawHighlight - * - * Creates and returns the highlight shape for the given state. - */ -mxCellHighlight.prototype.drawHighlight = function() -{ - this.shape = this.createShape(); - this.repaint(); - - if (!this.keepOnTop && this.shape.node.parentNode.firstChild != this.shape.node) - { - this.shape.node.parentNode.insertBefore(this.shape.node, this.shape.node.parentNode.firstChild); - } - - // Workaround to force a repaint in AppleWebKit - if (this.graph.model.isEdge(this.state.cell)) - { - mxUtils.repaintGraph(this.graph, this.shape.points[0]); - } -}; - -/** - * Function: createShape - * - * Creates and returns the highlight shape for the given state. - */ -mxCellHighlight.prototype.createShape = function() -{ - var shape = null; - - if (this.graph.model.isEdge(this.state.cell)) - { - shape = new mxPolyline(this.state.absolutePoints, - this.highlightColor, this.strokeWidth); - } - else - { - shape = new mxRectangleShape( new mxRectangle(), - null, this.highlightColor, this.strokeWidth); - } - - shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? - mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG; - shape.init(this.graph.getView().getOverlayPane()); - mxEvent.redirectMouseEvents(shape.node, this.graph, this.state); - - return shape; -}; - - -/** - * Function: repaint - * - * Updates the highlight after a change of the model or view. - */ -mxCellHighlight.prototype.repaint = function() -{ - if (this.state != null && this.shape != null) - { - if (this.graph.model.isEdge(this.state.cell)) - { - this.shape.points = this.state.absolutePoints; - } - else - { - this.shape.bounds = new mxRectangle(this.state.x - this.spacing, this.state.y - this.spacing, - this.state.width + 2 * this.spacing, this.state.height + 2 * this.spacing); - } - - // Uses cursor from shape in highlight - if (this.state.shape != null) - { - this.shape.setCursor(this.state.shape.getCursor()); - } - - var alpha = (!this.graph.model.isEdge(this.state.cell)) ? Number(this.state.style[mxConstants.STYLE_ROTATION] || '0') : 0; - - // Event-transparency - if (this.shape.dialect == mxConstants.DIALECT_SVG) - { - this.shape.node.setAttribute('style', 'pointer-events:none;'); - - if (alpha != 0) - { - var cx = this.state.getCenterX(); - var cy = this.state.getCenterY(); - var transform = 'rotate(' + alpha + ' ' + cx + ' ' + cy + ')'; - - this.shape.node.setAttribute('transform', transform); - } - } - else - { - this.shape.node.style.background = ''; - - if (alpha != 0) - { - this.shape.node.rotation = alpha; - } - } - - this.shape.redraw(); - } -}; - -/** - * Function: hide - * - * Resets the state of the cell marker. - */ -mxCellHighlight.prototype.hide = function() -{ - this.highlight(null); -}; - -/** - * Function: mark - * - * Marks the and fires a event. - */ -mxCellHighlight.prototype.highlight = function(state) -{ - if (this.state != state) - { - if (this.shape != null) - { - this.shape.destroy(); - this.shape = null; - } - - this.state = state; - - if (this.state != null) - { - this.drawHighlight(); - } - } -}; - -/** - * Function: destroy - * - * Destroys the handler and all its resources and DOM nodes. - */ -mxCellHighlight.prototype.destroy = function() -{ - this.graph.getView().removeListener(this.repaintHandler); - this.graph.getModel().removeListener(this.repaintHandler); - - this.graph.getView().removeListener(this.resetHandler); - this.graph.getModel().removeListener(this.resetHandler); - - if (this.shape != null) - { - this.shape.destroy(); - this.shape = null; - } -}; diff --git a/src/js/handler/mxCellMarker.js b/src/js/handler/mxCellMarker.js deleted file mode 100644 index b336278..0000000 --- a/src/js/handler/mxCellMarker.js +++ /dev/null @@ -1,419 +0,0 @@ -/** - * $Id: mxCellMarker.js,v 1.30 2011-07-15 12:57:50 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxCellMarker - * - * A helper class to process mouse locations and highlight cells. - * - * Helper class to highlight cells. To add a cell marker to an existing graph - * for highlighting all cells, the following code is used: - * - * (code) - * var marker = new mxCellMarker(graph); - * graph.addMouseListener({ - * mouseDown: function() {}, - * mouseMove: function(sender, me) - * { - * marker.process(me); - * }, - * mouseUp: function() {} - * }); - * (end) - * - * Event: mxEvent.MARK - * - * Fires after a cell has been marked or unmarked. The state - * property contains the marked or null if no state is marked. - * - * Constructor: mxCellMarker - * - * Constructs a new cell marker. - * - * Parameters: - * - * graph - Reference to the enclosing . - * validColor - Optional marker color for valid states. Default is - * . - * invalidColor - Optional marker color for invalid states. Default is - * . - * hotspot - Portion of the width and hight where a state intersects a - * given coordinate pair. A value of 0 means always highlight. Default is - * . - */ -function mxCellMarker(graph, validColor, invalidColor, hotspot) -{ - if (graph != null) - { - this.graph = graph; - this.validColor = (validColor != null) ? validColor : mxConstants.DEFAULT_VALID_COLOR; - this.invalidColor = (validColor != null) ? invalidColor : mxConstants.DEFAULT_INVALID_COLOR; - this.hotspot = (hotspot != null) ? hotspot : mxConstants.DEFAULT_HOTSPOT; - - this.highlight = new mxCellHighlight(graph); - } -}; - -/** - * Extends mxEventSource. - */ -mxCellMarker.prototype = new mxEventSource(); -mxCellMarker.prototype.constructor = mxCellMarker; - -/** - * Variable: graph - * - * Reference to the enclosing . - */ -mxCellMarker.prototype.graph = null; - -/** - * Variable: enabled - * - * Specifies if the marker is enabled. Default is true. - */ -mxCellMarker.prototype.enabled = true; - -/** - * Variable: hotspot - * - * Specifies the portion of the width and height that should trigger - * a highlight. The area around the center of the cell to be marked is used - * as the hotspot. Possible values are between 0 and 1. Default is - * mxConstants.DEFAULT_HOTSPOT. - */ -mxCellMarker.prototype.hotspot = mxConstants.DEFAULT_HOTSPOT; - -/** - * Variable: hotspotEnabled - * - * Specifies if the hotspot is enabled. Default is false. - */ -mxCellMarker.prototype.hotspotEnabled = false; - -/** - * Variable: validColor - * - * Holds the valid marker color. - */ -mxCellMarker.prototype.validColor = null; - -/** - * Variable: invalidColor - * - * Holds the invalid marker color. - */ -mxCellMarker.prototype.invalidColor = null; - -/** - * Variable: currentColor - * - * Holds the current marker color. - */ -mxCellMarker.prototype.currentColor = null; - -/** - * Variable: validState - * - * Holds the marked if it is valid. - */ -mxCellMarker.prototype.validState = null; - -/** - * Variable: markedState - * - * Holds the marked . - */ -mxCellMarker.prototype.markedState = null; - -/** - * Function: setEnabled - * - * Enables or disables event handling. This implementation - * updates . - * - * Parameters: - * - * enabled - Boolean that specifies the new enabled state. - */ -mxCellMarker.prototype.setEnabled = function(enabled) -{ - this.enabled = enabled; -}; - -/** - * Function: isEnabled - * - * Returns true if events are handled. This implementation - * returns . - */ -mxCellMarker.prototype.isEnabled = function() -{ - return this.enabled; -}; - -/** - * Function: setHotspot - * - * Sets the . - */ -mxCellMarker.prototype.setHotspot = function(hotspot) -{ - this.hotspot = hotspot; -}; - -/** - * Function: getHotspot - * - * Returns the . - */ -mxCellMarker.prototype.getHotspot = function() -{ - return this.hotspot; -}; - -/** - * Function: setHotspotEnabled - * - * Specifies whether the hotspot should be used in . - */ -mxCellMarker.prototype.setHotspotEnabled = function(enabled) -{ - this.hotspotEnabled = enabled; -}; - -/** - * Function: isHotspotEnabled - * - * Returns true if hotspot is used in . - */ -mxCellMarker.prototype.isHotspotEnabled = function() -{ - return this.hotspotEnabled; -}; - -/** - * Function: hasValidState - * - * Returns true if is not null. - */ -mxCellMarker.prototype.hasValidState = function() -{ - return this.validState != null; -}; - -/** - * Function: getValidState - * - * Returns the . - */ -mxCellMarker.prototype.getValidState = function() -{ - return this.validState; -}; - -/** - * Function: getMarkedState - * - * Returns the . - */ -mxCellMarker.prototype.getMarkedState = function() -{ - return this.markedState; -}; - -/** - * Function: reset - * - * Resets the state of the cell marker. - */ -mxCellMarker.prototype.reset = function() -{ - this.validState = null; - - if (this.markedState != null) - { - this.markedState = null; - this.unmark(); - } -}; - -/** - * Function: process - * - * Processes the given event and cell and marks the state returned by - * with the color returned by . If the - * markerColor is not null, then the state is stored in . If - * returns true, then the state is stored in - * regardless of the marker color. The state is returned regardless of the - * marker color and valid state. - */ -mxCellMarker.prototype.process = function(me) -{ - var state = null; - - if (this.isEnabled()) - { - state = this.getState(me); - var isValid = (state != null) ? this.isValidState(state) : false; - var color = this.getMarkerColor(me.getEvent(), state, isValid); - - if (isValid) - { - this.validState = state; - } - else - { - this.validState = null; - } - - if (state != this.markedState || color != this.currentColor) - { - this.currentColor = color; - - if (state != null && this.currentColor != null) - { - this.markedState = state; - this.mark(); - } - else if (this.markedState != null) - { - this.markedState = null; - this.unmark(); - } - } - } - - return state; -}; - -/** - * Function: markCell - * - * Marks the given cell using the given color, or if no color is specified. - */ -mxCellMarker.prototype.markCell = function(cell, color) -{ - var state = this.graph.getView().getState(cell); - - if (state != null) - { - this.currentColor = (color != null) ? color : this.validColor; - this.markedState = state; - this.mark(); - } -}; - -/** - * Function: mark - * - * Marks the and fires a event. - */ -mxCellMarker.prototype.mark = function() -{ - this.highlight.setHighlightColor(this.currentColor); - this.highlight.highlight(this.markedState); - this.fireEvent(new mxEventObject(mxEvent.MARK, 'state', this.markedState)); -}; - -/** - * Function: unmark - * - * Hides the marker and fires a event. - */ -mxCellMarker.prototype.unmark = function() -{ - this.mark(); -}; - -/** - * Function: isValidState - * - * Returns true if the given is a valid state. If this - * returns true, then the state is stored in . The return value - * of this method is used as the argument for . - */ -mxCellMarker.prototype.isValidState = function(state) -{ - return true; -}; - -/** - * Function: getMarkerColor - * - * Returns the valid- or invalidColor depending on the value of isValid. - * The given is ignored by this implementation. - */ -mxCellMarker.prototype.getMarkerColor = function(evt, state, isValid) -{ - return (isValid) ? this.validColor : this.invalidColor; -}; - -/** - * Function: getState - * - * Uses , and to return the - * for the given . - */ -mxCellMarker.prototype.getState = function(me) -{ - var view = this.graph.getView(); - cell = this.getCell(me); - var state = this.getStateToMark(view.getState(cell)); - - return (state != null && this.intersects(state, me)) ? state : null; -}; - -/** - * Function: getCell - * - * Returns the for the given event and cell. This returns the - * given cell. - */ -mxCellMarker.prototype.getCell = function(me) -{ - return me.getCell(); -}; - -/** - * Function: getStateToMark - * - * Returns the to be marked for the given under - * the mouse. This returns the given state. - */ -mxCellMarker.prototype.getStateToMark = function(state) -{ - return state; -}; - -/** - * Function: intersects - * - * Returns true if the given coordinate pair intersects the given state. - * This returns true if the is 0 or the coordinates are inside - * the hotspot for the given cell state. - */ -mxCellMarker.prototype.intersects = function(state, me) -{ - if (this.hotspotEnabled) - { - return mxUtils.intersectsHotspot(state, me.getGraphX(), me.getGraphY(), - this.hotspot, mxConstants.MIN_HOTSPOT_SIZE, - mxConstants.MAX_HOTSPOT_SIZE); - } - - return true; -}; - -/** - * Function: destroy - * - * Destroys the handler and all its resources and DOM nodes. - */ -mxCellMarker.prototype.destroy = function() -{ - this.graph.getView().removeListener(this.resetHandler); - this.graph.getModel().removeListener(this.resetHandler); - this.highlight.destroy(); -}; diff --git a/src/js/handler/mxCellTracker.js b/src/js/handler/mxCellTracker.js deleted file mode 100644 index 5adcd6a..0000000 --- a/src/js/handler/mxCellTracker.js +++ /dev/null @@ -1,149 +0,0 @@ -/** - * $Id: mxCellTracker.js,v 1.9 2011-08-28 09:49:46 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxCellTracker - * - * Event handler that highlights cells. Inherits from . - * - * Example: - * - * (code) - * new mxCellTracker(graph, '#00FF00'); - * (end) - * - * For detecting dragEnter, dragOver and dragLeave on cells, the following - * code can be used: - * - * (code) - * graph.addMouseListener( - * { - * cell: null, - * mouseDown: function(sender, me) { }, - * mouseMove: function(sender, me) - * { - * var tmp = me.getCell(); - * - * if (tmp != this.cell) - * { - * if (this.cell != null) - * { - * this.dragLeave(me.getEvent(), this.cell); - * } - * - * this.cell = tmp; - * - * if (this.cell != null) - * { - * this.dragEnter(me.getEvent(), this.cell); - * } - * } - * - * if (this.cell != null) - * { - * this.dragOver(me.getEvent(), this.cell); - * } - * }, - * mouseUp: function(sender, me) { }, - * dragEnter: function(evt, cell) - * { - * mxLog.debug('dragEnter', cell.value); - * }, - * dragOver: function(evt, cell) - * { - * mxLog.debug('dragOver', cell.value); - * }, - * dragLeave: function(evt, cell) - * { - * mxLog.debug('dragLeave', cell.value); - * } - * }); - * (end) - * - * Constructor: mxCellTracker - * - * Constructs an event handler that highlights cells. - * - * Parameters: - * - * graph - Reference to the enclosing . - * color - Color of the highlight. Default is blue. - * funct - Optional JavaScript function that is used to override - * . - */ -function mxCellTracker(graph, color, funct) -{ - mxCellMarker.call(this, graph, color); - - this.graph.addMouseListener(this); - - if (funct != null) - { - this.getCell = funct; - } - - // Automatic deallocation of memory - if (mxClient.IS_IE) - { - mxEvent.addListener(window, 'unload', mxUtils.bind(this, function() - { - this.destroy(); - })); - } -}; - -/** - * Extends mxCellMarker. - */ -mxCellTracker.prototype = new mxCellMarker(); -mxCellTracker.prototype.constructor = mxCellTracker; - -/** - * Function: mouseDown - * - * Ignores the event. The event is not consumed. - */ -mxCellTracker.prototype.mouseDown = function(sender, me) { }; - -/** - * Function: mouseMove - * - * Handles the event by highlighting the cell under the mousepointer if it - * is over the hotspot region of the cell. - */ -mxCellTracker.prototype.mouseMove = function(sender, me) -{ - if (this.isEnabled()) - { - this.process(me); - } -}; - -/** - * Function: mouseUp - * - * Handles the event by reseting the highlight. - */ -mxCellTracker.prototype.mouseUp = function(sender, me) -{ - this.reset(); -}; - -/** - * Function: destroy - * - * Destroys the object and all its resources and DOM nodes. This doesn't - * normally need to be called. It is called automatically when the window - * unloads. - */ -mxCellTracker.prototype.destroy = function() -{ - if (!this.destroyed) - { - this.destroyed = true; - - this.graph.removeMouseListener(this); - mxCellMarker.prototype.destroy.apply(this); - } -}; diff --git a/src/js/handler/mxConnectionHandler.js b/src/js/handler/mxConnectionHandler.js deleted file mode 100644 index 07daaf8..0000000 --- a/src/js/handler/mxConnectionHandler.js +++ /dev/null @@ -1,1969 +0,0 @@ -/** - * $Id: mxConnectionHandler.js,v 1.216 2012-12-07 15:17:37 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxConnectionHandler - * - * Graph event handler that creates new connections. Uses - * for finding and highlighting the source and target vertices and - * to create the edge instance. This handler is built-into - * and enabled using . - * - * Example: - * - * (code) - * new mxConnectionHandler(graph, function(source, target, style) - * { - * edge = new mxCell('', new mxGeometry()); - * edge.setEdge(true); - * edge.setStyle(style); - * edge.geometry.relative = true; - * return edge; - * }); - * (end) - * - * Here is an alternative solution that just sets a specific user object for - * new edges by overriding . - * - * (code) - * mxConnectionHandlerInsertEdge = mxConnectionHandler.prototype.insertEdge; - * mxConnectionHandler.prototype.insertEdge = function(parent, id, value, source, target, style) - * { - * value = 'Test'; - * - * return mxConnectionHandlerInsertEdge.apply(this, arguments); - * }; - * (end) - * - * Using images to trigger connections: - * - * This handler uses mxTerminalMarker to find the source and target cell for - * the new connection and creates a new edge using . The new edge is - * created using which in turn uses or creates a - * new default edge. - * - * The handler uses a "highlight-paradigm" for indicating if a cell is being - * used as a source or target terminal, as seen in MS Visio and other products. - * In order to allow both, moving and connecting cells at the same time, - * is used in the handler to determine the hotspot - * of a cell, that is, the region of the cell which is used to trigger a new - * connection. The constant is a value between 0 and 1 that specifies the - * amount of the width and height around the center to be used for the hotspot - * of a cell and its default value is 0.5. In addition, - * defines the minimum number of pixels for the - * width and height of the hotspot. - * - * This solution, while standards compliant, may be somewhat confusing because - * there is no visual indicator for the hotspot and the highlight is seen to - * switch on and off while the mouse is being moved in and out. Furthermore, - * this paradigm does not allow to create different connections depending on - * the highlighted hotspot as there is only one hotspot per cell and it - * normally does not allow cells to be moved and connected at the same time as - * there is no clear indication of the connectable area of the cell. - * - * To come across these issues, the handle has an additional hook - * with a default implementation that allows to create one icon to be used to - * trigger new connections. If this icon is specified, then new connections can - * only be created if the image is clicked while the cell is being highlighted. - * The hook may be overridden to create more than one - * for creating new connections, but the default implementation - * supports one image and is used as follows: - * - * In order to display the "connect image" whenever the mouse is over the cell, - * an DEFAULT_HOTSPOT of 1 should be used: - * - * (code) - * mxConstants.DEFAULT_HOTSPOT = 1; - * (end) - * - * In order to avoid confusion with the highlighting, the highlight color - * should not be used with a connect image: - * - * (code) - * mxConstants.HIGHLIGHT_COLOR = null; - * (end) - * - * To install the image, the connectImage field of the mxConnectionHandler must - * be assigned a new instance: - * - * (code) - * mxConnectionHandler.prototype.connectImage = new mxImage('images/green-dot.gif', 14, 14); - * (end) - * - * This will use the green-dot.gif with a width and height of 14 pixels as the - * image to trigger new connections. In createIcons the icon field of the - * handler will be set in order to remember the icon that has been clicked for - * creating the new connection. This field will be available under selectedIcon - * in the connect method, which may be overridden to take the icon that - * triggered the new connection into account. This is useful if more than one - * icon may be used to create a connection. - * - * Group: Events - * - * Event: mxEvent.START - * - * Fires when a new connection is being created by the user. The state - * property contains the state of the source cell. - * - * Event: mxEvent.CONNECT - * - * Fires between begin- and endUpdate in . The cell - * property contains the inserted edge, the event and target - * properties contain the respective arguments that were passed to (where - * target corresponds to the dropTarget argument). - * - * Note that the target is the cell under the mouse where the mouse button was released. - * Depending on the logic in the handler, this doesn't necessarily have to be the target - * of the inserted edge. To print the source, target or any optional ports IDs that the - * edge is connected to, the following code can be used. To get more details about the - * actual connection point, can be used. To resolve - * the port IDs, use . - * - * (code) - * graph.connectionHandler.addListener(mxEvent.CONNECT, function(sender, evt) - * { - * var edge = evt.getProperty('cell'); - * var source = graph.getModel().getTerminal(edge, true); - * var target = graph.getModel().getTerminal(edge, false); - * - * var style = graph.getCellStyle(edge); - * var sourcePortId = style[mxConstants.STYLE_SOURCE_PORT]; - * var targetPortId = style[mxConstants.STYLE_TARGET_PORT]; - * - * mxLog.show(); - * mxLog.debug('connect', edge, source.id, target.id, sourcePortId, targetPortId); - * }); - * (end) - * - * Event: mxEvent.RESET - * - * Fires when the method is invoked. - * - * Constructor: mxConnectionHandler - * - * Constructs an event handler that connects vertices using the specified - * factory method to create the new edges. Modify - * to setup the region on a cell which triggers - * the creation of a new connection or use connect icons as explained - * above. - * - * Parameters: - * - * graph - Reference to the enclosing . - * factoryMethod - Optional function to create the edge. The function takes - * the source and target as the first and second argument and an - * optional cell style from the preview as the third argument. It returns - * the that represents the new edge. - */ -function mxConnectionHandler(graph, factoryMethod) -{ - if (graph != null) - { - this.graph = graph; - this.factoryMethod = factoryMethod; - this.init(); - } -}; - -/** - * Extends mxEventSource. - */ -mxConnectionHandler.prototype = new mxEventSource(); -mxConnectionHandler.prototype.constructor = mxConnectionHandler; - -/** - * Variable: graph - * - * Reference to the enclosing . - */ -mxConnectionHandler.prototype.graph = null; - -/** - * Variable: factoryMethod - * - * Function that is used for creating new edges. The function takes the - * source and target as the first and second argument and returns - * a new that represents the edge. This is used in . - */ -mxConnectionHandler.prototype.factoryMethod = true; - -/** - * Variable: moveIconFront - * - * Specifies if icons should be displayed inside the graph container instead - * of the overlay pane. This is used for HTML labels on vertices which hide - * the connect icon. This has precendence over when set - * to true. Default is false. - */ -mxConnectionHandler.prototype.moveIconFront = false; - -/** - * Variable: moveIconBack - * - * Specifies if icons should be moved to the back of the overlay pane. This can - * be set to true if the icons of the connection handler conflict with other - * handles, such as the vertex label move handle. Default is false. - */ -mxConnectionHandler.prototype.moveIconBack = false; - -/** - * Variable: connectImage - * - * that is used to trigger the creation of a new connection. This - * is used in . Default is null. - */ -mxConnectionHandler.prototype.connectImage = null; - -/** - * Variable: targetConnectImage - * - * Specifies if the connect icon should be centered on the target state - * while connections are being previewed. Default is false. - */ -mxConnectionHandler.prototype.targetConnectImage = false; - -/** - * Variable: enabled - * - * Specifies if events are handled. Default is true. - */ -mxConnectionHandler.prototype.enabled = true; - -/** - * Variable: select - * - * Specifies if new edges should be selected. Default is true. - */ -mxConnectionHandler.prototype.select = true; - -/** - * Variable: createTarget - * - * Specifies if should be called if no target was under the - * mouse for the new connection. Setting this to true means the connection - * will be drawn as valid if no target is under the mouse, and - * will be called before the connection is created between - * the source cell and the newly created vertex in , which - * can be overridden to create a new target. Default is false. - */ -mxConnectionHandler.prototype.createTarget = false; - -/** - * Variable: marker - * - * Holds the used for finding source and target cells. - */ -mxConnectionHandler.prototype.marker = null; - -/** - * Variable: constraintHandler - * - * Holds the used for drawing and highlighting - * constraints. - */ -mxConnectionHandler.prototype.constraintHandler = null; - -/** - * Variable: error - * - * Holds the current validation error while connections are being created. - */ -mxConnectionHandler.prototype.error = null; - -/** - * Variable: waypointsEnabled - * - * Specifies if single clicks should add waypoints on the new edge. Default is - * false. - */ -mxConnectionHandler.prototype.waypointsEnabled = false; - -/** - * Variable: tapAndHoldEnabled - * - * Specifies if tap and hold should be used for starting connections on touch-based - * devices. Default is true. - */ -mxConnectionHandler.prototype.tapAndHoldEnabled = true; - -/** - * Variable: tapAndHoldDelay - * - * Specifies the time for a tap and hold. Default is 500 ms. - */ -mxConnectionHandler.prototype.tapAndHoldDelay = 500; - -/** - * Variable: tapAndHoldInProgress - * - * True if the timer for tap and hold events is running. - */ -mxConnectionHandler.prototype.tapAndHoldInProgress = false; - -/** - * Variable: tapAndHoldValid - * - * True as long as the timer is running and the touch events - * stay within the given . - */ -mxConnectionHandler.prototype.tapAndHoldValid = false; - -/** - * Variable: tapAndHoldTolerance - * - * Specifies the tolerance for a tap and hold. Default is 4 pixels. - */ -mxConnectionHandler.prototype.tapAndHoldTolerance = 4; - -/** - * Variable: initialTouchX - * - * Holds the x-coordinate of the intial touch event for tap and hold. - */ -mxConnectionHandler.prototype.initialTouchX = 0; - -/** - * Variable: initialTouchY - * - * Holds the y-coordinate of the intial touch event for tap and hold. - */ -mxConnectionHandler.prototype.initialTouchY = 0; - -/** - * Variable: ignoreMouseDown - * - * Specifies if the connection handler should ignore the state of the mouse - * button when highlighting the source. Default is false, that is, the - * handler only highlights the source if no button is being pressed. - */ -mxConnectionHandler.prototype.ignoreMouseDown = false; - -/** - * Variable: first - * - * Holds the where the mouseDown took place while the handler is - * active. - */ -mxConnectionHandler.prototype.first = null; - -/** - * Variable: connectIconOffset - * - * Holds the offset for connect icons during connection preview. - * Default is mxPoint(0, ). - * Note that placing the icon under the mouse pointer with an - * offset of (0,0) will affect hit detection. - */ -mxConnectionHandler.prototype.connectIconOffset = new mxPoint(0, mxConstants.TOOLTIP_VERTICAL_OFFSET); - -/** - * Variable: edgeState - * - * Optional that represents the preview edge while the - * handler is active. This is created in . - */ -mxConnectionHandler.prototype.edgeState = null; - -/** - * Variable: changeHandler - * - * Holds the change event listener for later removal. - */ -mxConnectionHandler.prototype.changeHandler = null; - -/** - * Variable: drillHandler - * - * Holds the drill event listener for later removal. - */ -mxConnectionHandler.prototype.drillHandler = null; - -/** - * Variable: mouseDownCounter - * - * Counts the number of mouseDown events since the start. The initial mouse - * down event counts as 1. - */ -mxConnectionHandler.prototype.mouseDownCounter = 0; - -/** - * Variable: movePreviewAway - * - * Switch to enable moving the preview away from the mousepointer. This is required in browsers - * where the preview cannot be made transparent to events and if the built-in hit detection on - * the HTML elements in the page should be used. Default is the value of . - */ -mxConnectionHandler.prototype.movePreviewAway = mxClient.IS_VML; - -/** - * Function: isEnabled - * - * Returns true if events are handled. This implementation - * returns . - */ -mxConnectionHandler.prototype.isEnabled = function() -{ - return this.enabled; -}; - -/** - * Function: setEnabled - * - * Enables or disables event handling. This implementation - * updates . - * - * Parameters: - * - * enabled - Boolean that specifies the new enabled state. - */ -mxConnectionHandler.prototype.setEnabled = function(enabled) -{ - this.enabled = enabled; -}; - -/** - * Function: isCreateTarget - * - * Returns . - */ -mxConnectionHandler.prototype.isCreateTarget = function() -{ - return this.createTarget; -}; - -/** - * Function: setCreateTarget - * - * Sets . - */ -mxConnectionHandler.prototype.setCreateTarget = function(value) -{ - this.createTarget = value; -}; - -/** - * Function: createShape - * - * Creates the preview shape for new connections. - */ -mxConnectionHandler.prototype.createShape = function() -{ - // Creates the edge preview - var shape = new mxPolyline([], mxConstants.INVALID_COLOR); - shape.isDashed = true; - shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? - mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG; - shape.init(this.graph.getView().getOverlayPane()); - - // Event-transparency - if (this.graph.dialect == mxConstants.DIALECT_SVG) - { - // Sets event transparency on the internal shapes that represent - // the actual dashed line on the screen - shape.pipe.setAttribute('style', 'pointer-events:none;'); - shape.innerNode.setAttribute('style', 'pointer-events:none;'); - } - else - { - // Workaround no event transparency for preview in IE - // FIXME: 3,3 pixel offset for custom hit detection in IE - var getState = mxUtils.bind(this, function(evt) - { - var pt = mxUtils.convertPoint(this.graph.container, mxEvent.getClientX(evt), mxEvent.getClientY(evt)); - - return this.graph.view.getState(this.graph.getCellAt(pt.x, pt.y)); - }); - - // Redirects events on the shape to the graph - mxEvent.redirectMouseEvents(shape.node, this.graph, getState); - } - - return shape; -}; - -/** - * Function: init - * - * Initializes the shapes required for this connection handler. This should - * be invoked if is assigned after the connection - * handler has been created. - */ -mxConnectionHandler.prototype.init = function() -{ - this.graph.addMouseListener(this); - this.marker = this.createMarker(); - this.constraintHandler = new mxConstraintHandler(this.graph); - - // Redraws the icons if the graph changes - this.changeHandler = mxUtils.bind(this, function(sender) - { - if (this.iconState != null) - { - this.iconState = this.graph.getView().getState(this.iconState.cell); - } - - if (this.iconState != null) - { - this.redrawIcons(this.icons, this.iconState); - } - else - { - this.destroyIcons(this.icons); - this.previous = null; - } - - this.constraintHandler.reset(); - }); - - this.graph.getModel().addListener(mxEvent.CHANGE, this.changeHandler); - this.graph.getView().addListener(mxEvent.SCALE, this.changeHandler); - this.graph.getView().addListener(mxEvent.TRANSLATE, this.changeHandler); - this.graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, this.changeHandler); - - // Removes the icon if we step into/up or start editing - this.drillHandler = mxUtils.bind(this, function(sender) - { - this.destroyIcons(this.icons); - }); - - this.graph.addListener(mxEvent.START_EDITING, this.drillHandler); - this.graph.getView().addListener(mxEvent.DOWN, this.drillHandler); - this.graph.getView().addListener(mxEvent.UP, this.drillHandler); -}; - -/** - * Function: isConnectableCell - * - * Returns true if the given cell is connectable. This is a hook to - * disable floating connections. This implementation returns true. - */ -mxConnectionHandler.prototype.isConnectableCell = function(cell) -{ - return true; -}; - -/** - * Function: createMarker - * - * Creates and returns the used in . - */ -mxConnectionHandler.prototype.createMarker = function() -{ - var marker = new mxCellMarker(this.graph); - marker.hotspotEnabled = true; - - // Overrides to return cell at location only if valid (so that - // there is no highlight for invalid cells) - marker.getCell = mxUtils.bind(this, function(evt, cell) - { - var cell = mxCellMarker.prototype.getCell.apply(marker, arguments); - this.error = null; - - if (!this.isConnectableCell(cell)) - { - return null; - } - - if (cell != null) - { - if (this.isConnecting()) - { - if (this.previous != null) - { - this.error = this.validateConnection(this.previous.cell, cell); - - if (this.error != null && this.error.length == 0) - { - cell = null; - - // Enables create target inside groups - if (this.isCreateTarget()) - { - this.error = null; - } - } - } - } - else if (!this.isValidSource(cell)) - { - cell = null; - } - } - else if (this.isConnecting() && !this.isCreateTarget() && - !this.graph.allowDanglingEdges) - { - this.error = ''; - } - - return cell; - }); - - // Sets the highlight color according to validateConnection - marker.isValidState = mxUtils.bind(this, function(state) - { - if (this.isConnecting()) - { - return this.error == null; - } - else - { - return mxCellMarker.prototype.isValidState.apply(marker, arguments); - } - }); - - // Overrides to use marker color only in highlight mode or for - // target selection - marker.getMarkerColor = mxUtils.bind(this, function(evt, state, isValid) - { - return (this.connectImage == null || this.isConnecting()) ? - mxCellMarker.prototype.getMarkerColor.apply(marker, arguments) : - null; - }); - - // Overrides to use hotspot only for source selection otherwise - // intersects always returns true when over a cell - marker.intersects = mxUtils.bind(this, function(state, evt) - { - if (this.connectImage != null || this.isConnecting()) - { - return true; - } - - return mxCellMarker.prototype.intersects.apply(marker, arguments); - }); - - return marker; -}; - -/** - * Function: start - * - * Starts a new connection for the given state and coordinates. - */ -mxConnectionHandler.prototype.start = function(state, x, y, edgeState) -{ - this.previous = state; - this.first = new mxPoint(x, y); - this.edgeState = (edgeState != null) ? edgeState : this.createEdgeState(null); - - // Marks the source state - this.marker.currentColor = this.marker.validColor; - this.marker.markedState = state; - this.marker.mark(); - - this.fireEvent(new mxEventObject(mxEvent.START, 'state', this.previous)); -}; - -/** - * Function: isConnecting - * - * Returns true if the source terminal has been clicked and a new - * connection is currently being previewed. - */ -mxConnectionHandler.prototype.isConnecting = function() -{ - return this.first != null && this.shape != null; -}; - -/** - * Function: isValidSource - * - * Returns for the given source terminal. - * - * Parameters: - * - * cell - that represents the source terminal. - */ -mxConnectionHandler.prototype.isValidSource = function(cell) -{ - return this.graph.isValidSource(cell); -}; - -/** - * Function: isValidTarget - * - * Returns true. The call to is implicit by calling - * in . This is an - * additional hook for disabling certain targets in this specific handler. - * - * Parameters: - * - * cell - that represents the target terminal. - */ -mxConnectionHandler.prototype.isValidTarget = function(cell) -{ - return true; -}; - -/** - * Function: validateConnection - * - * Returns the error message or an empty string if the connection for the - * given source target pair is not valid. Otherwise it returns null. This - * implementation uses . - * - * Parameters: - * - * source - that represents the source terminal. - * target - that represents the target terminal. - */ -mxConnectionHandler.prototype.validateConnection = function(source, target) -{ - if (!this.isValidTarget(target)) - { - return ''; - } - - return this.graph.getEdgeValidationError(null, source, target); -}; - -/** - * Function: getConnectImage - * - * Hook to return the used for the connection icon of the given - * . This implementation returns . - * - * Parameters: - * - * state - whose connect image should be returned. - */ -mxConnectionHandler.prototype.getConnectImage = function(state) -{ - return this.connectImage; -}; - -/** - * Function: isMoveIconToFrontForState - * - * Returns true if the state has a HTML label in the graph's container, otherwise - * it returns . - * - * Parameters: - * - * state - whose connect icons should be returned. - */ -mxConnectionHandler.prototype.isMoveIconToFrontForState = function(state) -{ - if (state.text != null && state.text.node.parentNode == this.graph.container) - { - return true; - } - - return this.moveIconFront; -}; - -/** - * Function: createIcons - * - * Creates the array that represent the connect icons for - * the given . - * - * Parameters: - * - * state - whose connect icons should be returned. - */ -mxConnectionHandler.prototype.createIcons = function(state) -{ - var image = this.getConnectImage(state); - - if (image != null && state != null) - { - this.iconState = state; - var icons = []; - - // Cannot use HTML for the connect icons because the icon receives all - // mouse move events in IE, must use VML and SVG instead even if the - // connect-icon appears behind the selection border and the selection - // border consumes the events before the icon gets a chance - var bounds = new mxRectangle(0, 0, image.width, image.height); - var icon = new mxImageShape(bounds, image.src, null, null, 0); - icon.preserveImageAspect = false; - - if (this.isMoveIconToFrontForState(state)) - { - icon.dialect = mxConstants.DIALECT_STRICTHTML; - icon.init(this.graph.container); - } - else - { - icon.dialect = (this.graph.dialect == mxConstants.DIALECT_SVG) ? - mxConstants.DIALECT_SVG : - mxConstants.DIALECT_VML; - icon.init(this.graph.getView().getOverlayPane()); - - // Move the icon back in the overlay pane - if (this.moveIconBack && icon.node.previousSibling != null) - { - icon.node.parentNode.insertBefore(icon.node, icon.node.parentNode.firstChild); - } - } - - icon.node.style.cursor = mxConstants.CURSOR_CONNECT; - - // Events transparency - var getState = mxUtils.bind(this, function() - { - return (this.currentState != null) ? this.currentState : state; - }); - - // Updates the local icon before firing the mouse down event. - var mouseDown = mxUtils.bind(this, function(evt) - { - if (!mxEvent.isConsumed(evt)) - { - this.icon = icon; - this.graph.fireMouseEvent(mxEvent.MOUSE_DOWN, - new mxMouseEvent(evt, getState())); - } - }); - - mxEvent.redirectMouseEvents(icon.node, this.graph, getState, mouseDown); - - icons.push(icon); - this.redrawIcons(icons, this.iconState); - - return icons; - } - - return null; -}; - -/** - * Function: redrawIcons - * - * Redraws the given array of . - * - * Parameters: - * - * icons - Optional array of to be redrawn. - */ -mxConnectionHandler.prototype.redrawIcons = function(icons, state) -{ - if (icons != null && icons[0] != null && state != null) - { - var pos = this.getIconPosition(icons[0], state); - icons[0].bounds.x = pos.x; - icons[0].bounds.y = pos.y; - icons[0].redraw(); - } -}; - -/** - * Function: redrawIcons - * - * Redraws the given array of . - * - * Parameters: - * - * icons - Optional array of to be redrawn. - */ -mxConnectionHandler.prototype.getIconPosition = function(icon, state) -{ - var scale = this.graph.getView().scale; - var cx = state.getCenterX(); - var cy = state.getCenterY(); - - if (this.graph.isSwimlane(state.cell)) - { - var size = this.graph.getStartSize(state.cell); - - cx = (size.width != 0) ? state.x + size.width * scale / 2 : cx; - cy = (size.height != 0) ? state.y + size.height * scale / 2 : cy; - } - - return new mxPoint(cx - icon.bounds.width / 2, - cy - icon.bounds.height / 2); -}; - -/** - * Function: destroyIcons - * - * Destroys the given array of . - * - * Parameters: - * - * icons - Optional array of to be destroyed. - */ -mxConnectionHandler.prototype.destroyIcons = function(icons) -{ - if (icons != null) - { - this.iconState = null; - - for (var i = 0; i < icons.length; i++) - { - icons[i].destroy(); - } - } -}; - -/** - * Function: isStartEvent - * - * Returns true if the given mouse down event should start this handler. The - * This implementation returns true if the event does not force marquee - * selection, and the currentConstraint and currentFocus of the - * are not null, or and are not null and - * is null or and are not null. - */ -mxConnectionHandler.prototype.isStartEvent = function(me) -{ - return !this.graph.isForceMarqueeEvent(me.getEvent()) && - ((this.constraintHandler.currentFocus != null && - this.constraintHandler.currentConstraint != null) || - (this.previous != null && this.error == null && - (this.icons == null || (this.icons != null && this.icon != null)))); -}; - -/** - * Function: mouseDown - * - * Handles the event by initiating a new connection. - */ -mxConnectionHandler.prototype.mouseDown = function(sender, me) -{ - this.mouseDownCounter++; - - if (this.isEnabled() && this.graph.isEnabled() && !me.isConsumed() && - !this.isConnecting() && this.isStartEvent(me)) - { - if (this.constraintHandler.currentConstraint != null && - this.constraintHandler.currentFocus != null && - this.constraintHandler.currentPoint != null) - { - this.sourceConstraint = this.constraintHandler.currentConstraint; - this.previous = this.constraintHandler.currentFocus; - this.first = this.constraintHandler.currentPoint.clone(); - } - else - { - // Stores the location of the initial mousedown - this.first = new mxPoint(me.getGraphX(), me.getGraphY()); - } - - this.edgeState = this.createEdgeState(me); - this.mouseDownCounter = 1; - - if (this.waypointsEnabled && this.shape == null) - { - this.waypoints = null; - this.shape = this.createShape(); - } - - // Stores the starting point in the geometry of the preview - if (this.previous == null && this.edgeState != null) - { - var pt = this.graph.getPointForEvent(me.getEvent()); - this.edgeState.cell.geometry.setTerminalPoint(pt, true); - } - - this.fireEvent(new mxEventObject(mxEvent.START, 'state', this.previous)); - - me.consume(); - } - // Handles connecting via tap and hold - else if (mxClient.IS_TOUCH && this.tapAndHoldEnabled && !this.tapAndHoldInProgress && - this.isEnabled() && this.graph.isEnabled() && !this.isConnecting()) - { - this.tapAndHoldInProgress = true; - this.initialTouchX = me.getX(); - this.initialTouchY = me.getY(); - var state = this.graph.view.getState(this.marker.getCell(me)); - - var handler = function() - { - if (this.tapAndHoldValid) - { - this.tapAndHold(me, state); - } - - this.tapAndHoldInProgress = false; - this.tapAndHoldValid = false; - }; - - if (this.tapAndHoldThread) - { - window.clearTimeout(this.tapAndHoldThread); - } - - this.tapAndHoldThread = window.setTimeout(mxUtils.bind(this, handler), this.tapAndHoldDelay); - this.tapAndHoldValid = true; - } - - this.selectedIcon = this.icon; - this.icon = null; -}; - -/** - * Function: tapAndHold - * - * Handles the by highlighting the . - * - * Parameters: - * - * me - that represents the touch event. - * state - Optional that is associated with the event. - */ -mxConnectionHandler.prototype.tapAndHold = function(me, state) -{ - if (state != null) - { - this.marker.currentColor = this.marker.validColor; - this.marker.markedState = state; - this.marker.mark(); - - this.first = new mxPoint(me.getGraphX(), me.getGraphY()); - this.edgeState = this.createEdgeState(me); - this.previous = state; - this.fireEvent(new mxEventObject(mxEvent.START, 'state', this.previous)); - } -}; - -/** - * Function: isImmediateConnectSource - * - * Returns true if a tap on the given source state should immediately start - * connecting. This implementation returns true if the state is not movable - * in the graph. - */ -mxConnectionHandler.prototype.isImmediateConnectSource = function(state) -{ - return !this.graph.isCellMovable(state.cell); -}; - -/** - * Function: createEdgeState - * - * Hook to return an which may be used during the preview. - * This implementation returns null. - * - * Use the following code to create a preview for an existing edge style: - * - * [code] - * graph.connectionHandler.createEdgeState = function(me) - * { - * var edge = graph.createEdge(null, null, null, null, null, 'edgeStyle=elbowEdgeStyle'); - * - * return new mxCellState(this.graph.view, edge, this.graph.getCellStyle(edge)); - * }; - * [/code] - */ -mxConnectionHandler.prototype.createEdgeState = function(me) -{ - return null; -}; - -/** - * Function: updateCurrentState - * - * Updates the current state for a given mouse move event by using - * the . - */ -mxConnectionHandler.prototype.updateCurrentState = function(me) -{ - var state = this.marker.process(me); - this.constraintHandler.update(me, this.first == null); - this.currentState = state; -}; - -/** - * Function: convertWaypoint - * - * Converts the given point from screen coordinates to model coordinates. - */ -mxConnectionHandler.prototype.convertWaypoint = function(point) -{ - var scale = this.graph.getView().getScale(); - var tr = this.graph.getView().getTranslate(); - - point.x = point.x / scale - tr.x; - point.y = point.y / scale - tr.y; -}; - -/** - * Function: mouseMove - * - * Handles the event by updating the preview edge or by highlighting - * a possible source or target terminal. - */ -mxConnectionHandler.prototype.mouseMove = function(sender, me) -{ - if (this.tapAndHoldValid) - { - this.tapAndHoldValid = - Math.abs(this.initialTouchX - me.getX()) < this.tapAndHoldTolerance && - Math.abs(this.initialTouchY - me.getY()) < this.tapAndHoldTolerance; - } - - if (!me.isConsumed() && (this.ignoreMouseDown || this.first != null || !this.graph.isMouseDown)) - { - // Handles special case when handler is disabled during highlight - if (!this.isEnabled() && this.currentState != null) - { - this.destroyIcons(this.icons); - this.currentState = null; - } - - if (this.first != null || (this.isEnabled() && this.graph.isEnabled())) - { - this.updateCurrentState(me); - } - - if (this.first != null) - { - var view = this.graph.getView(); - var scale = view.scale; - var point = new mxPoint(this.graph.snap(me.getGraphX() / scale) * scale, - this.graph.snap(me.getGraphY() / scale) * scale); - var constraint = null; - var current = point; - - // Uses the current point from the constraint handler if available - if (this.constraintHandler.currentConstraint != null && - this.constraintHandler.currentFocus != null && - this.constraintHandler.currentPoint != null) - { - constraint = this.constraintHandler.currentConstraint; - current = this.constraintHandler.currentPoint.clone(); - } - - var pt2 = this.first; - - // Moves the connect icon with the mouse - if (this.selectedIcon != null) - { - var w = this.selectedIcon.bounds.width; - var h = this.selectedIcon.bounds.height; - - if (this.currentState != null && this.targetConnectImage) - { - var pos = this.getIconPosition(this.selectedIcon, this.currentState); - this.selectedIcon.bounds.x = pos.x; - this.selectedIcon.bounds.y = pos.y; - } - else - { - var bounds = new mxRectangle(me.getGraphX() + this.connectIconOffset.x, - me.getGraphY() + this.connectIconOffset.y, w, h); - this.selectedIcon.bounds = bounds; - } - - this.selectedIcon.redraw(); - } - - // Uses edge state to compute the terminal points - if (this.edgeState != null) - { - this.edgeState.absolutePoints = [null, (this.currentState != null) ? null : current]; - this.graph.view.updateFixedTerminalPoint(this.edgeState, this.previous, true, this.sourceConstraint); - - if (this.currentState != null) - { - if (constraint == null) - { - constraint = this.graph.getConnectionConstraint(this.edgeState, this.previous, false); - } - - this.edgeState.setAbsoluteTerminalPoint(null, false); - this.graph.view.updateFixedTerminalPoint(this.edgeState, this.currentState, false, constraint); - } - - // Scales and translates the waypoints to the model - var realPoints = null; - - if (this.waypoints != null) - { - realPoints = []; - - for (var i = 0; i < this.waypoints.length; i++) - { - var pt = this.waypoints[i].clone(); - this.convertWaypoint(pt); - realPoints[i] = pt; - } - } - - this.graph.view.updatePoints(this.edgeState, realPoints, this.previous, this.currentState); - this.graph.view.updateFloatingTerminalPoints(this.edgeState, this.previous, this.currentState); - current = this.edgeState.absolutePoints[this.edgeState.absolutePoints.length - 1]; - pt2 = this.edgeState.absolutePoints[0]; - } - else - { - if (this.currentState != null) - { - if (this.constraintHandler.currentConstraint == null) - { - var tmp = this.getTargetPerimeterPoint(this.currentState, me); - - if (tmp != null) - { - current = tmp; - } - } - } - - // Computes the source perimeter point - if (this.sourceConstraint == null && this.previous != null) - { - var next = (this.waypoints != null && this.waypoints.length > 0) ? - this.waypoints[0] : current; - var tmp = this.getSourcePerimeterPoint(this.previous, next, me); - - if (tmp != null) - { - pt2 = tmp; - } - } - } - - // Makes sure the cell under the mousepointer can be detected - // by moving the preview shape away from the mouse. This - // makes sure the preview shape does not prevent the detection - // of the cell under the mousepointer even for slow gestures. - if (this.currentState == null && this.movePreviewAway) - { - var tmp = pt2; - - if (this.edgeState != null && this.edgeState.absolutePoints.length > 2) - { - var tmp2 = this.edgeState.absolutePoints[this.edgeState.absolutePoints.length - 2]; - - if (tmp2 != null) - { - tmp = tmp2; - } - } - - var dx = current.x - tmp.x; - var dy = current.y - tmp.y; - - var len = Math.sqrt(dx * dx + dy * dy); - - if (len == 0) - { - return; - } - - current.x -= dx * 4 / len; - current.y -= dy * 4 / len; - } - - // Creates the preview shape (lazy) - if (this.shape == null) - { - var dx = Math.abs(point.x - this.first.x); - var dy = Math.abs(point.y - this.first.y); - - if (dx > this.graph.tolerance || dy > this.graph.tolerance) - { - this.shape = this.createShape(); - - // Revalidates current connection - this.updateCurrentState(me); - } - } - - // Updates the points in the preview edge - if (this.shape != null) - { - if (this.edgeState != null) - { - this.shape.points = this.edgeState.absolutePoints; - } - else - { - var pts = [pt2]; - - if (this.waypoints != null) - { - pts = pts.concat(this.waypoints); - } - - pts.push(current); - this.shape.points = pts; - } - - this.drawPreview(); - } - - mxEvent.consume(me.getEvent()); - me.consume(); - } - else if(!this.isEnabled() || !this.graph.isEnabled()) - { - this.constraintHandler.reset(); - } - else if (this.previous != this.currentState && this.edgeState == null) - { - this.destroyIcons(this.icons); - this.icons = null; - - // Sets the cursor on the current shape - if (this.currentState != null && this.error == null) - { - this.icons = this.createIcons(this.currentState); - - if (this.icons == null) - { - this.currentState.setCursor(mxConstants.CURSOR_CONNECT); - me.consume(); - } - } - - this.previous = this.currentState; - } - else if (this.previous == this.currentState && this.currentState != null && this.icons == null && - !this.graph.isMouseDown) - { - // Makes sure that no cursors are changed - me.consume(); - } - - if (this.constraintHandler.currentConstraint != null) - { - this.marker.reset(); - } - - if (!this.graph.isMouseDown && this.currentState != null && this.icons != null) - { - var hitsIcon = false; - var target = me.getSource(); - - for (var i = 0; i < this.icons.length && !hitsIcon; i++) - { - hitsIcon = target == this.icons[i].node || target.parentNode == this.icons[i].node; - } - - if (!hitsIcon) - { - this.updateIcons(this.currentState, this.icons, me); - } - } - } - else - { - this.constraintHandler.reset(); - } -}; - -/** - * Function: getTargetPerimeterPoint - * - * Returns the perimeter point for the given target state. - * - * Parameters: - * - * state - that represents the target cell state. - * me - that represents the mouse move. - */ -mxConnectionHandler.prototype.getTargetPerimeterPoint = function(state, me) -{ - var result = null; - var view = state.view; - var targetPerimeter = view.getPerimeterFunction(state); - - if (targetPerimeter != null) - { - var next = (this.waypoints != null && this.waypoints.length > 0) ? - this.waypoints[this.waypoints.length - 1] : - new mxPoint(this.previous.getCenterX(), this.previous.getCenterY()); - var tmp = targetPerimeter(view.getPerimeterBounds(state), - this.edgeState, next, false); - - if (tmp != null) - { - result = tmp; - } - } - else - { - result = new mxPoint(state.getCenterX(), state.getCenterY()); - } - - return result; -}; - -/** - * Function: getSourcePerimeterPoint - * - * Hook to update the icon position(s) based on a mouseOver event. This is - * an empty implementation. - * - * Parameters: - * - * state - that represents the target cell state. - * next - that represents the next point along the previewed edge. - * me - that represents the mouse move. - */ -mxConnectionHandler.prototype.getSourcePerimeterPoint = function(state, next, me) -{ - var result = null; - var view = state.view; - var sourcePerimeter = view.getPerimeterFunction(state); - - if (sourcePerimeter != null) - { - var tmp = sourcePerimeter(view.getPerimeterBounds(state), state, next, false); - - if (tmp != null) - { - result = tmp; - } - } - else - { - result = new mxPoint(state.getCenterX(), state.getCenterY()); - } - - return result; -}; - - -/** - * Function: updateIcons - * - * Hook to update the icon position(s) based on a mouseOver event. This is - * an empty implementation. - * - * Parameters: - * - * state - under the mouse. - * icons - Array of currently displayed icons. - * me - that contains the mouse event. - */ -mxConnectionHandler.prototype.updateIcons = function(state, icons, me) -{ - // empty -}; - -/** - * Function: isStopEvent - * - * Returns true if the given mouse up event should stop this handler. The - * connection will be created if is null. Note that this is only - * called if is true. This implemtation returns true - * if there is a cell state in the given event. - */ -mxConnectionHandler.prototype.isStopEvent = function(me) -{ - return me.getState() != null; -}; - -/** - * Function: addWaypoint - * - * Adds the waypoint for the given event to . - */ -mxConnectionHandler.prototype.addWaypointForEvent = function(me) -{ - var point = mxUtils.convertPoint(this.graph.container, me.getX(), me.getY()); - var dx = Math.abs(point.x - this.first.x); - var dy = Math.abs(point.y - this.first.y); - var addPoint = this.waypoints != null || (this.mouseDownCounter > 1 && - (dx > this.graph.tolerance || dy > this.graph.tolerance)); - - if (addPoint) - { - if (this.waypoints == null) - { - this.waypoints = []; - } - - var scale = this.graph.view.scale; - var point = new mxPoint(this.graph.snap(me.getGraphX() / scale) * scale, - this.graph.snap(me.getGraphY() / scale) * scale); - this.waypoints.push(point); - } -}; - -/** - * Function: mouseUp - * - * Handles the event by inserting the new connection. - */ -mxConnectionHandler.prototype.mouseUp = function(sender, me) -{ - if (!me.isConsumed() && this.isConnecting()) - { - if (this.waypointsEnabled && !this.isStopEvent(me)) - { - this.addWaypointForEvent(me); - me.consume(); - - return; - } - - // Inserts the edge if no validation error exists - if (this.error == null) - { - var source = (this.previous != null) ? this.previous.cell : null; - var target = null; - - if (this.constraintHandler.currentConstraint != null && - this.constraintHandler.currentFocus != null) - { - target = this.constraintHandler.currentFocus.cell; - } - - if (target == null && this.marker.hasValidState()) - { - target = this.marker.validState.cell; - } - - this.connect(source, target, me.getEvent(), me.getCell()); - } - else - { - // Selects the source terminal for self-references - if (this.previous != null && this.marker.validState != null && - this.previous.cell == this.marker.validState.cell) - { - this.graph.selectCellForEvent(this.marker.source, evt); - } - - // Displays the error message if it is not an empty string, - // for empty error messages, the event is silently dropped - if (this.error.length > 0) - { - this.graph.validationAlert(this.error); - } - } - - // Redraws the connect icons and resets the handler state - this.destroyIcons(this.icons); - me.consume(); - } - - if (this.first != null) - { - this.reset(); - } - - this.tapAndHoldInProgress = false; - this.tapAndHoldValid = false; -}; - -/** - * Function: reset - * - * Resets the state of this handler. - */ -mxConnectionHandler.prototype.reset = function() -{ - if (this.shape != null) - { - this.shape.destroy(); - this.shape = null; - } - - this.destroyIcons(this.icons); - this.icons = null; - this.marker.reset(); - this.constraintHandler.reset(); - this.selectedIcon = null; - this.edgeState = null; - this.previous = null; - this.error = null; - this.sourceConstraint = null; - this.mouseDownCounter = 0; - this.first = null; - this.icon = null; - - this.fireEvent(new mxEventObject(mxEvent.RESET)); -}; - -/** - * Function: drawPreview - * - * Redraws the preview edge using the color and width returned by - * and . - */ -mxConnectionHandler.prototype.drawPreview = function() -{ - var valid = this.error == null; - var color = this.getEdgeColor(valid); - - if (this.shape.dialect == mxConstants.DIALECT_SVG) - { - this.shape.innerNode.setAttribute('stroke', color); - } - else - { - this.shape.node.strokecolor = color; - } - - this.shape.strokewidth = this.getEdgeWidth(valid); - this.shape.redraw(); - - // Workaround to force a repaint in AppleWebKit - mxUtils.repaintGraph(this.graph, this.shape.points[1]); -}; - -/** - * Function: getEdgeColor - * - * Returns the color used to draw the preview edge. This returns green if - * there is no edge validation error and red otherwise. - * - * Parameters: - * - * valid - Boolean indicating if the color for a valid edge should be - * returned. - */ -mxConnectionHandler.prototype.getEdgeColor = function(valid) -{ - return (valid) ? mxConstants.VALID_COLOR : mxConstants.INVALID_COLOR; -}; - -/** - * Function: getEdgeWidth - * - * Returns the width used to draw the preview edge. This returns 3 if - * there is no edge validation error and 1 otherwise. - * - * Parameters: - * - * valid - Boolean indicating if the width for a valid edge should be - * returned. - */ -mxConnectionHandler.prototype.getEdgeWidth = function(valid) -{ - return (valid) ? 3 : 1; -}; - -/** - * Function: connect - * - * Connects the given source and target using a new edge. This - * implementation uses to create the edge. - * - * Parameters: - * - * source - that represents the source terminal. - * target - that represents the target terminal. - * evt - Mousedown event of the connect gesture. - * dropTarget - that represents the cell under the mouse when it was - * released. - */ -mxConnectionHandler.prototype.connect = function(source, target, evt, dropTarget) -{ - if (target != null || this.isCreateTarget() || this.graph.allowDanglingEdges) - { - // Uses the common parent of source and target or - // the default parent to insert the edge - var model = this.graph.getModel(); - var edge = null; - - model.beginUpdate(); - try - { - if (source != null && target == null && this.isCreateTarget()) - { - target = this.createTargetVertex(evt, source); - - if (target != null) - { - dropTarget = this.graph.getDropTarget([target], evt, dropTarget); - - // Disables edges as drop targets if the target cell was created - // FIXME: Should not shift if vertex was aligned (same in Java) - if (dropTarget == null || !this.graph.getModel().isEdge(dropTarget)) - { - var pstate = this.graph.getView().getState(dropTarget); - - if (pstate != null) - { - var tmp = model.getGeometry(target); - tmp.x -= pstate.origin.x; - tmp.y -= pstate.origin.y; - } - } - else - { - dropTarget = this.graph.getDefaultParent(); - } - - this.graph.addCell(target, dropTarget); - } - } - - var parent = this.graph.getDefaultParent(); - - if (source != null && target != null && - model.getParent(source) == model.getParent(target) && - model.getParent(model.getParent(source)) != model.getRoot()) - { - parent = model.getParent(source); - - if ((source.geometry != null && source.geometry.relative) && - (target.geometry != null && target.geometry.relative)) - { - parent = model.getParent(parent); - } - } - - // Uses the value of the preview edge state for inserting - // the new edge into the graph - var value = null; - var style = null; - - if (this.edgeState != null) - { - value = this.edgeState.cell.value; - style = this.edgeState.cell.style; - } - - edge = this.insertEdge(parent, null, value, source, target, style); - - if (edge != null) - { - // Updates the connection constraints - this.graph.setConnectionConstraint(edge, source, true, this.sourceConstraint); - this.graph.setConnectionConstraint(edge, target, false, this.constraintHandler.currentConstraint); - - // Uses geometry of the preview edge state - if (this.edgeState != null) - { - model.setGeometry(edge, this.edgeState.cell.geometry); - } - - // Makes sure the edge has a non-null, relative geometry - var geo = model.getGeometry(edge); - - if (geo == null) - { - geo = new mxGeometry(); - geo.relative = true; - - model.setGeometry(edge, geo); - } - - // Uses scaled waypoints in geometry - if (this.waypoints != null && this.waypoints.length > 0) - { - var s = this.graph.view.scale; - var tr = this.graph.view.translate; - geo.points = []; - - for (var i = 0; i < this.waypoints.length; i++) - { - var pt = this.waypoints[i]; - geo.points.push(new mxPoint(pt.x / s - tr.x, pt.y / s - tr.y)); - } - } - - if (target == null) - { - var pt = this.graph.getPointForEvent(evt, false); - pt.x -= this.graph.panDx / this.graph.view.scale; - pt.y -= this.graph.panDy / this.graph.view.scale; - geo.setTerminalPoint(pt, false); - } - - this.fireEvent(new mxEventObject(mxEvent.CONNECT, - 'cell', edge, 'event', evt, 'target', dropTarget)); - } - } - catch (e) - { - mxLog.show(); - mxLog.debug(e.message); - } - finally - { - model.endUpdate(); - } - - if (this.select) - { - this.selectCells(edge, target); - } - } -}; - -/** - * Function: selectCells - * - * Selects the given edge after adding a new connection. The target argument - * contains the target vertex if one has been inserted. - */ -mxConnectionHandler.prototype.selectCells = function(edge, target) -{ - this.graph.setSelectionCell(edge); -}; - -/** - * Function: insertEdge - * - * Creates, inserts and returns the new edge for the given parameters. This - * implementation does only use if is defined, - * otherwise will be used. - */ -mxConnectionHandler.prototype.insertEdge = function(parent, id, value, source, target, style) -{ - if (this.factoryMethod == null) - { - return this.graph.insertEdge(parent, id, value, source, target, style); - } - else - { - var edge = this.createEdge(value, source, target, style); - edge = this.graph.addEdge(edge, parent, source, target); - - return edge; - } -}; - -/** - * Function: createTargetVertex - * - * Hook method for creating new vertices on the fly if no target was - * under the mouse. This is only called if is true and - * returns null. - * - * Parameters: - * - * evt - Mousedown event of the connect gesture. - * source - that represents the source terminal. - */ -mxConnectionHandler.prototype.createTargetVertex = function(evt, source) -{ - // Uses the first non-relative source - var geo = this.graph.getCellGeometry(source); - - while (geo != null && geo.relative) - { - source = this.graph.getModel().getParent(source); - geo = this.graph.getCellGeometry(source); - } - - var clone = this.graph.cloneCells([source])[0]; - var geo = this.graph.getModel().getGeometry(clone); - - if (geo != null) - { - var point = this.graph.getPointForEvent(evt); - geo.x = this.graph.snap(point.x - geo.width / 2) - this.graph.panDx / this.graph.view.scale; - geo.y = this.graph.snap(point.y - geo.height / 2) - this.graph.panDy / this.graph.view.scale; - - // Aligns with source if within certain tolerance - if (this.first != null) - { - var sourceState = this.graph.view.getState(source); - - if (sourceState != null) - { - var tol = this.getAlignmentTolerance(); - - if (Math.abs(this.graph.snap(this.first.x) - - this.graph.snap(point.x)) <= tol) - { - geo.x = sourceState.x; - } - else if (Math.abs(this.graph.snap(this.first.y) - - this.graph.snap(point.y)) <= tol) - { - geo.y = sourceState.y; - } - } - } - } - - return clone; -}; - -/** - * Function: getAlignmentTolerance - * - * Returns the tolerance for aligning new targets to sources. - */ -mxConnectionHandler.prototype.getAlignmentTolerance = function() -{ - return (this.graph.isGridEnabled()) ? - this.graph.gridSize : this.graph.tolerance; -}; - -/** - * Function: createEdge - * - * Creates and returns a new edge using if one exists. If - * no factory method is defined, then a new default edge is returned. The - * source and target arguments are informal, the actual connection is - * setup later by the caller of this function. - * - * Parameters: - * - * value - Value to be used for creating the edge. - * source - that represents the source terminal. - * target - that represents the target terminal. - * style - Optional style from the preview edge. - */ -mxConnectionHandler.prototype.createEdge = function(value, source, target, style) -{ - var edge = null; - - // Creates a new edge using the factoryMethod - if (this.factoryMethod != null) - { - edge = this.factoryMethod(source, target, style); - } - - if (edge == null) - { - edge = new mxCell(value || ''); - edge.setEdge(true); - edge.setStyle(style); - - var geo = new mxGeometry(); - geo.relative = true; - edge.setGeometry(geo); - } - - return edge; -}; - -/** - * Function: destroy - * - * Destroys the handler and all its resources and DOM nodes. This should be - * called on all instances. It is called automatically for the built-in - * instance created for each . - */ -mxConnectionHandler.prototype.destroy = function() -{ - this.graph.removeMouseListener(this); - - if (this.shape != null) - { - this.shape.destroy(); - this.shape = null; - } - - if (this.marker != null) - { - this.marker.destroy(); - this.marker = null; - } - - if (this.constraintHandler != null) - { - this.constraintHandler.destroy(); - this.constraintHandler = null; - } - - if (this.changeHandler != null) - { - this.graph.getModel().removeListener(this.changeHandler); - this.graph.getView().removeListener(this.changeHandler); - this.changeHandler = null; - } - - if (this.drillHandler != null) - { - this.graph.removeListener(this.drillHandler); - this.graph.getView().removeListener(this.drillHandler); - this.drillHandler = null; - } -}; diff --git a/src/js/handler/mxConstraintHandler.js b/src/js/handler/mxConstraintHandler.js deleted file mode 100644 index 39b3ab6..0000000 --- a/src/js/handler/mxConstraintHandler.js +++ /dev/null @@ -1,308 +0,0 @@ -/** - * $Id: mxConstraintHandler.js,v 1.15 2012-11-01 16:13:41 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxConstraintHandler - * - * Handles constraints on connection targets. This class is in charge of - * showing fixed points when the mouse is over a vertex and handles constraints - * to establish new connections. - * - * Constructor: mxConstraintHandler - * - * Constructs an new constraint handler. - * - * Parameters: - * - * graph - Reference to the enclosing . - * factoryMethod - Optional function to create the edge. The function takes - * the source and target as the first and second argument and - * returns the that represents the new edge. - */ -function mxConstraintHandler(graph) -{ - this.graph = graph; -}; - -/** - * Variable: pointImage - * - * to be used as the image for fixed connection points. - */ -mxConstraintHandler.prototype.pointImage = new mxImage(mxClient.imageBasePath + '/point.gif', 5, 5); - -/** - * Variable: graph - * - * Reference to the enclosing . - */ -mxConstraintHandler.prototype.graph = null; - -/** - * Variable: enabled - * - * Specifies if events are handled. Default is true. - */ -mxConstraintHandler.prototype.enabled = true; - -/** - * Variable: highlightColor - * - * Specifies the color for the highlight. Default is . - */ -mxConstraintHandler.prototype.highlightColor = mxConstants.DEFAULT_VALID_COLOR; - -/** - * Function: isEnabled - * - * Returns true if events are handled. This implementation - * returns . - */ -mxConstraintHandler.prototype.isEnabled = function() -{ - return this.enabled; -}; - -/** - * Function: setEnabled - * - * Enables or disables event handling. This implementation - * updates . - * - * Parameters: - * - * enabled - Boolean that specifies the new enabled state. - */ -mxConstraintHandler.prototype.setEnabled = function(enabled) -{ - this.enabled = enabled; -}; - -/** - * Function: reset - * - * Resets the state of this handler. - */ -mxConstraintHandler.prototype.reset = function() -{ - if (this.focusIcons != null) - { - for (var i = 0; i < this.focusIcons.length; i++) - { - this.focusIcons[i].destroy(); - } - - this.focusIcons = null; - } - - if (this.focusHighlight != null) - { - this.focusHighlight.destroy(); - this.focusHighlight = null; - } - - this.currentConstraint = null; - this.currentFocusArea = null; - this.currentPoint = null; - this.currentFocus = null; - this.focusPoints = null; -}; - -/** - * Function: getTolerance - * - * Returns the tolerance to be used for intersecting connection points. - */ -mxConstraintHandler.prototype.getTolerance = function() -{ - return this.graph.getTolerance(); -}; - -/** - * Function: getImageForConstraint - * - * Returns the tolerance to be used for intersecting connection points. - */ -mxConstraintHandler.prototype.getImageForConstraint = function(state, constraint, point) -{ - return this.pointImage; -}; - -/** - * Function: isEventIgnored - * - * Returns true if the given should be ignored in . This - * implementation always returns false. - */ -mxConstraintHandler.prototype.isEventIgnored = function(me, source) -{ - return false; -}; - -/** - * Function: update - * - * Updates the state of this handler based on the given . - * Source is a boolean indicating if the cell is a source or target. - */ -mxConstraintHandler.prototype.update = function(me, source) -{ - if (this.isEnabled() && !this.isEventIgnored(me)) - { - var tol = this.getTolerance(); - var mouse = new mxRectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol); - var connectable = (me.getCell() != null) ? this.graph.isCellConnectable(me.getCell()) : false; - - if ((this.currentFocusArea == null || (!mxUtils.intersects(this.currentFocusArea, mouse) || - (me.getState() != null && this.currentFocus != null && connectable)))) - { - this.currentFocusArea = null; - - if (me.getState() != this.currentFocus) - { - this.currentFocus = null; - this.constraints = (me.getState() != null && connectable) ? - this.graph.getAllConnectionConstraints(me.getState(), source) : null; - - // Only uses cells which have constraints - if (this.constraints != null) - { - this.currentFocus = me.getState(); - this.currentFocusArea = new mxRectangle(me.getState().x, me.getState().y, me.getState().width, me.getState().height); - - if (this.focusIcons != null) - { - for (var i = 0; i < this.focusIcons.length; i++) - { - this.focusIcons[i].destroy(); - } - - this.focusIcons = null; - this.focusPoints = null; - } - - this.focusIcons = []; - this.focusPoints = []; - - for (var i = 0; i < this.constraints.length; i++) - { - var cp = this.graph.getConnectionPoint(me.getState(), this.constraints[i]); - var img = this.getImageForConstraint(me.getState(), this.constraints[i], cp); - - var src = img.src; - var bounds = new mxRectangle(cp.x - img.width / 2, - cp.y - img.height / 2, img.width, img.height); - var icon = new mxImageShape(bounds, src); - icon.dialect = (this.graph.dialect == mxConstants.DIALECT_SVG) ? - mxConstants.DIALECT_SVG : - mxConstants.DIALECT_VML; - icon.init(this.graph.getView().getOverlayPane()); - - // Move the icon behind all other overlays - if (icon.node.previousSibling != null) - { - icon.node.parentNode.insertBefore(icon.node, icon.node.parentNode.firstChild); - } - - var getState = mxUtils.bind(this, function() - { - return (this.currentFocus != null) ? this.currentFocus : me.getState(); - }); - - icon.redraw(); - - mxEvent.redirectMouseEvents(icon.node, this.graph, getState); - this.currentFocusArea.add(icon.bounds); - this.focusIcons.push(icon); - this.focusPoints.push(cp); - } - - this.currentFocusArea.grow(tol); - } - else if (this.focusIcons != null) - { - if (this.focusHighlight != null) - { - this.focusHighlight.destroy(); - this.focusHighlight = null; - } - - for (var i = 0; i < this.focusIcons.length; i++) - { - this.focusIcons[i].destroy(); - } - - this.focusIcons = null; - this.focusPoints = null; - } - } - } - - this.currentConstraint = null; - this.currentPoint = null; - - if (this.focusIcons != null && this.constraints != null && - (me.getState() == null || this.currentFocus == me.getState())) - { - for (var i = 0; i < this.focusIcons.length; i++) - { - if (mxUtils.intersects(this.focusIcons[i].bounds, mouse)) - { - this.currentConstraint = this.constraints[i]; - this.currentPoint = this.focusPoints[i]; - - var tmp = this.focusIcons[i].bounds.clone(); - tmp.grow((mxClient.IS_IE) ? 3 : 2); - - if (mxClient.IS_IE) - { - tmp.width -= 1; - tmp.height -= 1; - } - - if (this.focusHighlight == null) - { - var hl = new mxRectangleShape(tmp, null, this.highlightColor, 3); - hl.dialect = (this.graph.dialect == mxConstants.DIALECT_SVG) ? - mxConstants.DIALECT_SVG : - mxConstants.DIALECT_VML; - hl.init(this.graph.getView().getOverlayPane()); - this.focusHighlight = hl; - - var getState = mxUtils.bind(this, function() - { - return (this.currentFocus != null) ? this.currentFocus : me.getState(); - }); - - mxEvent.redirectMouseEvents(hl.node, this.graph, getState/*, mouseDown*/); - } - else - { - this.focusHighlight.bounds = tmp; - this.focusHighlight.redraw(); - } - - break; - } - } - } - - if (this.currentConstraint == null && - this.focusHighlight != null) - { - this.focusHighlight.destroy(); - this.focusHighlight = null; - } - } -}; - -/** - * Function: destroy - * - * Destroy this handler. - */ -mxConstraintHandler.prototype.destroy = function() -{ - this.reset(); -}; \ No newline at end of file diff --git a/src/js/handler/mxEdgeHandler.js b/src/js/handler/mxEdgeHandler.js deleted file mode 100644 index 2028342..0000000 --- a/src/js/handler/mxEdgeHandler.js +++ /dev/null @@ -1,1529 +0,0 @@ -/** - * $Id: mxEdgeHandler.js,v 1.178 2012-09-12 09:16:23 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxEdgeHandler - * - * Graph event handler that reconnects edges and modifies control points and - * the edge label location. Uses for finding and - * highlighting new source and target vertices. This handler is automatically - * created in for each selected edge. - * - * To enable adding/removing control points, the following code can be used: - * - * (code) - * mxEdgeHandler.prototype.addEnabled = true; - * mxEdgeHandler.prototype.removeEnabled = true; - * (end) - * - * Note: This experimental feature is not recommended for production use. - * - * Constructor: mxEdgeHandler - * - * Constructs an edge handler for the specified . - * - * Parameters: - * - * state - of the cell to be handled. - */ -function mxEdgeHandler(state) -{ - if (state != null) - { - this.state = state; - this.init(); - } -}; - -/** - * Variable: graph - * - * Reference to the enclosing . - */ -mxEdgeHandler.prototype.graph = null; - -/** - * Variable: state - * - * Reference to the being modified. - */ -mxEdgeHandler.prototype.state = null; - -/** - * Variable: marker - * - * Holds the which is used for highlighting terminals. - */ -mxEdgeHandler.prototype.marker = null; - -/** - * Variable: constraintHandler - * - * Holds the used for drawing and highlighting - * constraints. - */ -mxEdgeHandler.prototype.constraintHandler = null; - -/** - * Variable: error - * - * Holds the current validation error while a connection is being changed. - */ -mxEdgeHandler.prototype.error = null; - -/** - * Variable: shape - * - * Holds the that represents the preview edge. - */ -mxEdgeHandler.prototype.shape = null; - -/** - * Variable: bends - * - * Holds the that represent the points. - */ -mxEdgeHandler.prototype.bends = null; - -/** - * Variable: labelShape - * - * Holds the that represents the label position. - */ -mxEdgeHandler.prototype.labelShape = null; - -/** - * Variable: cloneEnabled - * - * Specifies if cloning by control-drag is enabled. Default is true. - */ -mxEdgeHandler.prototype.cloneEnabled = true; - -/** - * Variable: addEnabled - * - * Specifies if adding bends by shift-click is enabled. Default is false. - * Note: This experimental feature is not recommended for production use. - */ -mxEdgeHandler.prototype.addEnabled = false; - -/** - * Variable: removeEnabled - * - * Specifies if removing bends by shift-click is enabled. Default is false. - * Note: This experimental feature is not recommended for production use. - */ -mxEdgeHandler.prototype.removeEnabled = false; - -/** - * Variable: preferHtml - * - * Specifies if bends should be added to the graph container. This is updated - * in based on whether the edge or one of its terminals has an HTML - * label in the container. - */ -mxEdgeHandler.prototype.preferHtml = false; - -/** - * Variable: allowHandleBoundsCheck - * - * Specifies if the bounds of handles should be used for hit-detection in IE - * Default is true. - */ -mxEdgeHandler.prototype.allowHandleBoundsCheck = true; - -/** - * Variable: snapToTerminals - * - * Specifies if waypoints should snap to the routing centers of terminals. - * Default is false. - */ -mxEdgeHandler.prototype.snapToTerminals = false; - -/** - * Variable: crisp - * - * Specifies if the edge handles should be rendered in crisp mode. Default is - * true. - */ -mxEdgeHandler.prototype.crisp = true; - -/** - * Variable: handleImage - * - * Optional to be used as handles. Default is null. - */ -mxEdgeHandler.prototype.handleImage = null; - -/** - * Variable: tolerance - * - * Optional tolerance for hit-detection in . Default is 0. - */ -mxEdgeHandler.prototype.tolerance = 0; - -/** - * Function: init - * - * Initializes the shapes required for this edge handler. - */ -mxEdgeHandler.prototype.init = function() -{ - this.graph = this.state.view.graph; - this.marker = this.createMarker(); - this.constraintHandler = new mxConstraintHandler(this.graph); - - // Clones the original points from the cell - // and makes sure at least one point exists - this.points = []; - - // Uses the absolute points of the state - // for the initial configuration and preview - this.abspoints = this.getSelectionPoints(this.state); - this.shape = this.createSelectionShape(this.abspoints); - this.shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? - mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG; - this.shape.init(this.graph.getView().getOverlayPane()); - this.shape.node.style.cursor = mxConstants.CURSOR_MOVABLE_EDGE; - - // Event handling - var md = (mxClient.IS_TOUCH) ? 'touchstart' : 'mousedown'; - var mm = (mxClient.IS_TOUCH) ? 'touchmove' : 'mousemove'; - var mu = (mxClient.IS_TOUCH) ? 'touchend' : 'mouseup'; - - mxEvent.addListener(this.shape.node, 'dblclick', - mxUtils.bind(this, function(evt) - { - this.graph.dblClick(evt, this.state.cell); - }) - ); - mxEvent.addListener(this.shape.node, md, - mxUtils.bind(this, function(evt) - { - if (this.addEnabled && this.isAddPointEvent(evt)) - { - this.addPoint(this.state, evt); - } - else - { - this.graph.fireMouseEvent(mxEvent.MOUSE_DOWN, - new mxMouseEvent(evt, this.state)); - } - }) - ); - mxEvent.addListener(this.shape.node, mm, - mxUtils.bind(this, function(evt) - { - var cell = this.state.cell; - - // Finds the cell under the mouse if the edge is being connected - // in which case the edge is never highlighted as it cannot - // be its own source or target terminal (transparent preview) - if (this.index != null) - { - var pt = mxUtils.convertPoint(this.graph.container, - mxEvent.getClientX(evt), mxEvent.getClientY(evt)); - cell = this.graph.getCellAt(pt.x, pt.y); - - // Swimlane content area is transparent in this case - if (this.graph.isSwimlane(cell) && this.graph.hitsSwimlaneContent(cell, pt.x, pt.y)) - { - cell = null; - } - } - - this.graph.fireMouseEvent(mxEvent.MOUSE_MOVE, - new mxMouseEvent(evt, this.graph.getView().getState(cell))); - }) - ); - mxEvent.addListener(this.shape.node, mu, - mxUtils.bind(this, function(evt) - { - this.graph.fireMouseEvent(mxEvent.MOUSE_UP, - new mxMouseEvent(evt, this.state)); - }) - ); - - // Updates preferHtml - this.preferHtml = this.state.text != null && - this.state.text.node.parentNode == this.graph.container; - - if (!this.preferHtml) - { - // Checks source terminal - var sourceState = this.state.getVisibleTerminalState(true); - - if (sourceState != null) - { - this.preferHtml = sourceState.text != null && - sourceState.text.node.parentNode == this.graph.container; - } - - if (!this.preferHtml) - { - // Checks target terminal - var targetState = this.state.getVisibleTerminalState(false); - - if (targetState != null) - { - this.preferHtml = targetState.text != null && - targetState.text.node.parentNode == this.graph.container; - } - } - } - - // Creates bends for the non-routed absolute points - // or bends that don't correspond to points - if (this.graph.getSelectionCount() < mxGraphHandler.prototype.maxCells || - mxGraphHandler.prototype.maxCells <= 0) - { - this.bends = this.createBends(); - } - - // Adds a rectangular handle for the label position - this.label = new mxPoint(this.state.absoluteOffset.x, this.state.absoluteOffset.y); - this.labelShape = new mxRectangleShape(new mxRectangle(), - mxConstants.LABEL_HANDLE_FILLCOLOR, - mxConstants.HANDLE_STROKECOLOR); - this.initBend(this.labelShape); - this.labelShape.node.style.cursor = mxConstants.CURSOR_LABEL_HANDLE; - mxEvent.redirectMouseEvents(this.labelShape.node, this.graph, this.state); - - this.redraw(); -}; - -/** - * Function: isAddPointEvent - * - * Returns true if the given event is a trigger to add a new point. This - * implementation returns true if shift is pressed. - */ -mxEdgeHandler.prototype.isAddPointEvent = function(evt) -{ - return mxEvent.isShiftDown(evt); -}; - -/** - * Function: isRemovePointEvent - * - * Returns true if the given event is a trigger to remove a point. This - * implementation returns true if shift is pressed. - */ -mxEdgeHandler.prototype.isRemovePointEvent = function(evt) -{ - return mxEvent.isShiftDown(evt); -}; - -/** - * Function: getSelectionPoints - * - * Returns the list of points that defines the selection stroke. - */ -mxEdgeHandler.prototype.getSelectionPoints = function(state) -{ - return state.absolutePoints; -}; - -/** - * Function: createSelectionShape - * - * Creates the shape used to draw the selection border. - */ -mxEdgeHandler.prototype.createSelectionShape = function(points) -{ - var shape = new mxPolyline(points, this.getSelectionColor()); - shape.strokewidth = this.getSelectionStrokeWidth(); - shape.isDashed = this.isSelectionDashed(); - - return shape; -}; - -/** - * Function: getSelectionColor - * - * Returns . - */ -mxEdgeHandler.prototype.getSelectionColor = function() -{ - return mxConstants.EDGE_SELECTION_COLOR; -}; - -/** - * Function: getSelectionStrokeWidth - * - * Returns . - */ -mxEdgeHandler.prototype.getSelectionStrokeWidth = function() -{ - return mxConstants.EDGE_SELECTION_STROKEWIDTH; -}; - -/** - * Function: isSelectionDashed - * - * Returns . - */ -mxEdgeHandler.prototype.isSelectionDashed = function() -{ - return mxConstants.EDGE_SELECTION_DASHED; -}; - -/** - * Function: isConnectableCell - * - * Returns true if the given cell is connectable. This is a hook to - * disable floating connections. This implementation returns true. - */ -mxEdgeHandler.prototype.isConnectableCell = function(cell) -{ - return true; -}; - -/** - * Function: createMarker - * - * Creates and returns the used in . - */ -mxEdgeHandler.prototype.createMarker = function() -{ - var marker = new mxCellMarker(this.graph); - var self = this; // closure - - // Only returns edges if they are connectable and never returns - // the edge that is currently being modified - marker.getCell = function(me) - { - var cell = mxCellMarker.prototype.getCell.apply(this, arguments); - - if (!self.isConnectableCell(cell)) - { - return null; - } - - var model = self.graph.getModel(); - - if (cell == self.state.cell || (cell != null && - !self.graph.connectableEdges && model.isEdge(cell))) - { - cell = null; - } - - return cell; - }; - - // Sets the highlight color according to validateConnection - marker.isValidState = function(state) - { - var model = self.graph.getModel(); - var other = self.graph.view.getTerminalPort(state, - self.graph.view.getState(model.getTerminal(self.state.cell, - !self.isSource)), !self.isSource); - var otherCell = (other != null) ? other.cell : null; - var source = (self.isSource) ? state.cell : otherCell; - var target = (self.isSource) ? otherCell : state.cell; - - // Updates the error message of the handler - self.error = self.validateConnection(source, target); - - return self.error == null; - }; - - return marker; -}; - -/** - * Function: validateConnection - * - * Returns the error message or an empty string if the connection for the - * given source, target pair is not valid. Otherwise it returns null. This - * implementation uses . - * - * Parameters: - * - * source - that represents the source terminal. - * target - that represents the target terminal. - */ -mxEdgeHandler.prototype.validateConnection = function(source, target) -{ - return this.graph.getEdgeValidationError(this.state.cell, source, target); -}; - -/** - * Function: createBends - * - * Creates and returns the bends used for modifying the edge. This is - * typically an array of . - */ - mxEdgeHandler.prototype.createBends = function() - { - var cell = this.state.cell; - var bends = []; - - for (var i = 0; i < this.abspoints.length; i++) - { - if (this.isHandleVisible(i)) - { - var source = i == 0; - var target = i == this.abspoints.length - 1; - var terminal = source || target; - - if (terminal || this.graph.isCellBendable(cell)) - { - var bend = this.createHandleShape(i); - this.initBend(bend); - - if (mxClient.IS_TOUCH) - { - bend.node.setAttribute('pointer-events', 'none'); - } - - if (this.isHandleEnabled(i)) - { - if (mxClient.IS_TOUCH) - { - var getState = mxUtils.bind(this, function(evt) - { - var pt = mxUtils.convertPoint(this.graph.container, mxEvent.getClientX(evt), mxEvent.getClientY(evt)); - - return this.graph.view.getState(this.graph.getCellAt(pt.x, pt.y)); - }); - - mxEvent.redirectMouseEvents(bend.node, this.graph, getState); - } - else - { - bend.node.style.cursor = mxConstants.CURSOR_BEND_HANDLE; - mxEvent.redirectMouseEvents(bend.node, this.graph, this.state); - } - } - - bends.push(bend); - - if (!terminal) - { - this.points.push(new mxPoint(0,0)); - bend.node.style.visibility = 'hidden'; - } - } - } - } - - return bends; -}; -/** - * Function: isHandleEnabled - * - * Creates the shape used to display the given bend. - */ -mxEdgeHandler.prototype.isHandleEnabled = function(index) -{ - return true; -}; - -/** - * Function: isHandleVisible - * - * Returns true if the handle at the given index is visible. - */ -mxEdgeHandler.prototype.isHandleVisible = function(index) -{ - return true; -}; - -/** - * Function: createHandleShape - * - * Creates the shape used to display the given bend. Note that the index may be - * null for special cases, such as when called from - * . - */ -mxEdgeHandler.prototype.createHandleShape = function(index) -{ - if (this.handleImage != null) - { - return new mxImageShape(new mxRectangle(0, 0, this.handleImage.width, this.handleImage.height), this.handleImage.src); - } - else - { - var s = mxConstants.HANDLE_SIZE; - - if (this.preferHtml) - { - s -= 1; - } - - return new mxRectangleShape(new mxRectangle(0, 0, s, s), mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR); - } -}; - -/** - * Function: initBend - * - * Helper method to initialize the given bend. - * - * Parameters: - * - * bend - that represents the bend to be initialized. - */ -mxEdgeHandler.prototype.initBend = function(bend) -{ - bend.crisp = this.crisp; - - if (this.preferHtml) - { - bend.dialect = mxConstants.DIALECT_STRICTHTML; - bend.init(this.graph.container); - } - else - { - bend.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? - mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG; - bend.init(this.graph.getView().getOverlayPane()); - } -}; - -/** - * Function: getHandleForEvent - * - * Returns the index of the handle for the given event. - */ -mxEdgeHandler.prototype.getHandleForEvent = function(me) -{ - // Finds the handle that triggered the event - if (this.bends != null) - { - // Connection highlight may consume events before they reach sizer handle - var tol = this.tolerance; - var hit = (this.allowHandleBoundsCheck && (mxClient.IS_IE || tol > 0)) ? - new mxRectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol) : null; - - for (var i = 0; i < this.bends.length; i++) - { - if (me.isSource(this.bends[i]) || (hit != null && - this.bends[i].node.style.visibility != 'hidden' && - mxUtils.intersects(this.bends[i].bounds, hit))) - { - return i; - } - } - } - - if (me.isSource(this.labelShape) || me.isSource(this.state.text)) - { - // Workaround for SELECT element not working in Webkit - if ((!mxClient.IS_SF && !mxClient.IS_GC) || me.getSource().nodeName != 'SELECT') - { - return mxEvent.LABEL_HANDLE; - } - } - - return null; -}; - -/** - * Function: mouseDown - * - * Handles the event by checking if a special element of the handler - * was clicked, in which case the index parameter is non-null. The - * indices may be one of or the number of the respective - * control point. The source and target points are used for reconnecting - * the edge. - */ -mxEdgeHandler.prototype.mouseDown = function(sender, me) -{ - var handle = null; - - // Handles the case where the state in the event points to another - // cell if the cell has a HTML label which sits on top of the handles - // NOTE: Commented out. This should not be required as all HTML labels - // are in order an do not appear behind the handles. - //if (mxClient.IS_SVG || me.getState() == this.state) - { - handle = this.getHandleForEvent(me); - } - - if (handle != null && !me.isConsumed() && this.graph.isEnabled() && - !this.graph.isForceMarqueeEvent(me.getEvent())) - { - if (this.removeEnabled && this.isRemovePointEvent(me.getEvent())) - { - this.removePoint(this.state, handle); - } - else if (handle != mxEvent.LABEL_HANDLE || this.graph.isLabelMovable(me.getCell())) - { - this.start(me.getX(), me.getY(), handle); - } - - me.consume(); - } -}; - -/** - * Function: start - * - * Starts the handling of the mouse gesture. - */ -mxEdgeHandler.prototype.start = function(x, y, index) -{ - this.startX = x; - this.startY = y; - - this.isSource = (this.bends == null) ? false : index == 0; - this.isTarget = (this.bends == null) ? false : index == this.bends.length - 1; - this.isLabel = index == mxEvent.LABEL_HANDLE; - - if (this.isSource || this.isTarget) - { - var cell = this.state.cell; - var terminal = this.graph.model.getTerminal(cell, this.isSource); - - if ((terminal == null && this.graph.isTerminalPointMovable(cell, this.isSource)) || - (terminal != null && this.graph.isCellDisconnectable(cell, terminal, this.isSource))) - { - this.index = index; - } - } - else - { - this.index = index; - } -}; - -/** - * Function: clonePreviewState - * - * Returns a clone of the current preview state for the given point and terminal. - */ -mxEdgeHandler.prototype.clonePreviewState = function(point, terminal) -{ - return this.state.clone(); -}; - -/** - * Function: getSnapToTerminalTolerance - * - * Returns the tolerance for the guides. Default value is - * gridSize * scale / 2. - */ -mxEdgeHandler.prototype.getSnapToTerminalTolerance = function() -{ - return this.graph.gridSize * this.graph.view.scale / 2; -}; - -/** - * Function: getPointForEvent - * - * Returns the point for the given event. - */ -mxEdgeHandler.prototype.getPointForEvent = function(me) -{ - var point = new mxPoint(me.getGraphX(), me.getGraphY()); - - var tt = this.getSnapToTerminalTolerance(); - var view = this.graph.getView(); - var overrideX = false; - var overrideY = false; - - if (this.snapToTerminals && tt > 0) - { - function snapToPoint(pt) - { - if (pt != null) - { - var x = pt.x; - - if (Math.abs(point.x - x) < tt) - { - point.x = x; - overrideX = true; - } - - var y = pt.y; - - if (Math.abs(point.y - y) < tt) - { - point.y = y; - overrideY = true; - } - } - } - - // Temporary function - function snapToTerminal(terminal) - { - if (terminal != null) - { - snapToPoint.call(this, new mxPoint(view.getRoutingCenterX(terminal), - view.getRoutingCenterY(terminal))); - } - }; - - snapToTerminal.call(this, this.state.getVisibleTerminalState(true)); - snapToTerminal.call(this, this.state.getVisibleTerminalState(false)); - - if (this.abspoints != null) - { - for (var i = 0; i < this.abspoints; i++) - { - if (i != this.index) - { - snapToPoint.call(this, this.abspoints[i]); - } - } - } - } - - if (this.graph.isGridEnabledEvent(me.getEvent())) - { - var scale = view.scale; - var tr = view.translate; - - if (!overrideX) - { - point.x = (this.graph.snap(point.x / scale - tr.x) + tr.x) * scale; - } - - if (!overrideY) - { - point.y = (this.graph.snap(point.y / scale - tr.y) + tr.y) * scale; - } - } - - return point; -}; - -/** - * Function: getPreviewTerminalState - * - * Updates the given preview state taking into account the state of the constraint handler. - */ -mxEdgeHandler.prototype.getPreviewTerminalState = function(me) -{ - this.constraintHandler.update(me, this.isSource); - this.marker.process(me); - var currentState = this.marker.getValidState(); - var result = null; - - if (this.constraintHandler.currentFocus != null && - this.constraintHandler.currentConstraint != null) - { - this.marker.reset(); - } - - if (currentState != null) - { - result = currentState; - } - else if (this.constraintHandler.currentConstraint != null && - this.constraintHandler.currentFocus != null) - { - result = this.constraintHandler.currentFocus; - } - - return result; -}; - -/** - * Function: getPreviewPoints - * - * Updates the given preview state taking into account the state of the constraint handler. - */ -mxEdgeHandler.prototype.getPreviewPoints = function(point) -{ - var geometry = this.graph.getCellGeometry(this.state.cell); - var points = (geometry.points != null) ? geometry.points.slice() : null; - - if (!this.isSource && !this.isTarget) - { - this.convertPoint(point, false); - - if (points == null) - { - points = [point]; - } - else - { - points[this.index - 1] = point; - } - } - else if (this.graph.resetEdgesOnConnect) - { - points = null; - } - - return points; -}; - -/** - * Function: updatePreviewState - * - * Updates the given preview state taking into account the state of the constraint handler. - */ -mxEdgeHandler.prototype.updatePreviewState = function(edge, point, terminalState) -{ - // Computes the points for the edge style and terminals - var sourceState = (this.isSource) ? terminalState : this.state.getVisibleTerminalState(true); - var targetState = (this.isTarget) ? terminalState : this.state.getVisibleTerminalState(false); - - var sourceConstraint = this.graph.getConnectionConstraint(edge, sourceState, true); - var targetConstraint = this.graph.getConnectionConstraint(edge, targetState, false); - - var constraint = this.constraintHandler.currentConstraint; - - if (constraint == null) - { - constraint = new mxConnectionConstraint(); - } - - if (this.isSource) - { - sourceConstraint = constraint; - } - else if (this.isTarget) - { - targetConstraint = constraint; - } - - if (!this.isSource || sourceState != null) - { - edge.view.updateFixedTerminalPoint(edge, sourceState, true, sourceConstraint); - } - - if (!this.isTarget || targetState != null) - { - edge.view.updateFixedTerminalPoint(edge, targetState, false, targetConstraint); - } - - if ((this.isSource || this.isTarget) && terminalState == null) - { - edge.setAbsoluteTerminalPoint(point, this.isSource); - - if (this.marker.getMarkedState() == null) - { - this.error = (this.graph.allowDanglingEdges) ? null : ''; - } - } - - edge.view.updatePoints(edge, this.points, sourceState, targetState); - edge.view.updateFloatingTerminalPoints(edge, sourceState, targetState); -}; - -/** - * Function: mouseMove - * - * Handles the event by updating the preview. - */ -mxEdgeHandler.prototype.mouseMove = function(sender, me) -{ - if (this.index != null && this.marker != null) - { - var point = this.getPointForEvent(me); - - if (this.isLabel) - { - this.label.x = point.x; - this.label.y = point.y; - } - else - { - this.points = this.getPreviewPoints(point); - var terminalState = (this.isSource || this.isTarget) ? this.getPreviewTerminalState(me) : null; - var clone = this.clonePreviewState(point, (terminalState != null) ? terminalState.cell : null); - this.updatePreviewState(clone, point, terminalState); - - // Sets the color of the preview to valid or invalid, updates the - // points of the preview and redraws - var color = (this.error == null) ? this.marker.validColor : - this.marker.invalidColor; - this.setPreviewColor(color); - this.abspoints = clone.absolutePoints; - this.active = true; - } - - this.drawPreview(); - mxEvent.consume(me.getEvent()); - me.consume(); - } - // Workaround for disabling the connect highlight when over handle - else if (mxClient.IS_IE && this.getHandleForEvent(me) != null) - { - me.consume(false); - } -}; - -/** - * Function: mouseUp - * - * Handles the event to applying the previewed changes on the edge by - * using , or . - */ -mxEdgeHandler.prototype.mouseUp = function(sender, me) -{ - if (this.index != null && this.marker != null) - { - var edge = this.state.cell; - - // Ignores event if mouse has not been moved - if (me.getX() != this.startX || me.getY() != this.startY) - { - // Displays the reason for not carriying out the change - // if there is an error message with non-zero length - if (this.error != null) - { - if (this.error.length > 0) - { - this.graph.validationAlert(this.error); - } - } - else if (this.isLabel) - { - this.moveLabel(this.state, this.label.x, this.label.y); - } - else if (this.isSource || this.isTarget) - { - var terminal = null; - - if (this.constraintHandler.currentConstraint != null && - this.constraintHandler.currentFocus != null) - { - terminal = this.constraintHandler.currentFocus.cell; - } - - if (terminal == null && this.marker.hasValidState()) - { - terminal = this.marker.validState.cell; - } - - if (terminal != null) - { - edge = this.connect(edge, terminal, this.isSource, - this.graph.isCloneEvent(me.getEvent()) && this.cloneEnabled && - this.graph.isCellsCloneable(), me); - } - else if (this.graph.isAllowDanglingEdges()) - { - var pt = this.abspoints[(this.isSource) ? 0 : this.abspoints.length - 1]; - pt.x = pt.x / this.graph.view.scale - this.graph.view.translate.x; - pt.y = pt.y / this.graph.view.scale - this.graph.view.translate.y; - - var pstate = this.graph.getView().getState( - this.graph.getModel().getParent(edge)); - - if (pstate != null) - { - pt.x -= pstate.origin.x; - pt.y -= pstate.origin.y; - } - - pt.x -= this.graph.panDx / this.graph.view.scale; - pt.y -= this.graph.panDy / this.graph.view.scale; - - // Destroys and rectreates this handler - this.changeTerminalPoint(edge, pt, this.isSource); - } - } - else if (this.active) - { - this.changePoints(edge, this.points); - } - else - { - this.graph.getView().invalidate(this.state.cell); - this.graph.getView().revalidate(this.state.cell); - } - } - - // Resets the preview color the state of the handler if this - // handler has not been recreated - if (this.marker != null) - { - this.reset(); - - // Updates the selection if the edge has been cloned - if (edge != this.state.cell) - { - this.graph.setSelectionCell(edge); - } - } - - me.consume(); - } -}; - -/** - * Function: reset - * - * Resets the state of this handler. - */ -mxEdgeHandler.prototype.reset = function() -{ - this.error = null; - this.index = null; - this.label = null; - this.points = null; - this.active = false; - this.isLabel = false; - this.isSource = false; - this.isTarget = false; - this.marker.reset(); - this.constraintHandler.reset(); - this.setPreviewColor(mxConstants.EDGE_SELECTION_COLOR); - this.redraw(); -}; - -/** - * Function: setPreviewColor - * - * Sets the color of the preview to the given value. - */ -mxEdgeHandler.prototype.setPreviewColor = function(color) -{ - if (this.shape != null && this.shape.node != null) - { - if (this.shape.dialect == mxConstants.DIALECT_SVG) - { - this.shape.innerNode.setAttribute('stroke', color); - } - else - { - this.shape.node.strokecolor = color; - } - } -}; - -/** - * Function: convertPoint - * - * Converts the given point in-place from screen to unscaled, untranslated - * graph coordinates and applies the grid. Returns the given, modified - * point instance. - * - * Parameters: - * - * point - to be converted. - * gridEnabled - Boolean that specifies if the grid should be applied. - */ -mxEdgeHandler.prototype.convertPoint = function(point, gridEnabled) -{ - var scale = this.graph.getView().getScale(); - var tr = this.graph.getView().getTranslate(); - - if (gridEnabled) - { - point.x = this.graph.snap(point.x); - point.y = this.graph.snap(point.y); - } - - point.x = Math.round(point.x / scale - tr.x); - point.y = Math.round(point.y / scale - tr.y); - - var pstate = this.graph.getView().getState( - this.graph.getModel().getParent(this.state.cell)); - - if (pstate != null) - { - point.x -= pstate.origin.x; - point.y -= pstate.origin.y; - } - - return point; -}; - -/** - * Function: moveLabel - * - * Changes the coordinates for the label of the given edge. - * - * Parameters: - * - * edge - that represents the edge. - * x - Integer that specifies the x-coordinate of the new location. - * y - Integer that specifies the y-coordinate of the new location. - */ -mxEdgeHandler.prototype.moveLabel = function(edgeState, x, y) -{ - var model = this.graph.getModel(); - var geometry = model.getGeometry(edgeState.cell); - - if (geometry != null) - { - geometry = geometry.clone(); - - // Resets the relative location stored inside the geometry - var pt = this.graph.getView().getRelativePoint(edgeState, x, y); - geometry.x = pt.x; - geometry.y = pt.y; - - // Resets the offset inside the geometry to find the offset - // from the resulting point - var scale = this.graph.getView().scale; - geometry.offset = new mxPoint(0, 0); - var pt = this.graph.view.getPoint(edgeState, geometry); - geometry.offset = new mxPoint((x - pt.x) / scale, (y - pt.y) / scale); - - model.setGeometry(edgeState.cell, geometry); - } -}; - -/** - * Function: connect - * - * Changes the terminal or terminal point of the given edge in the graph - * model. - * - * Parameters: - * - * edge - that represents the edge to be reconnected. - * terminal - that represents the new terminal. - * isSource - Boolean indicating if the new terminal is the source or - * target terminal. - * isClone - Boolean indicating if the new connection should be a clone of - * the old edge. - * me - that contains the mouse up event. - */ -mxEdgeHandler.prototype.connect = function(edge, terminal, isSource, isClone, me) -{ - var model = this.graph.getModel(); - var parent = model.getParent(edge); - - model.beginUpdate(); - try - { - // Clones and adds the cell - if (isClone) - { - var clone = edge.clone(); - model.add(parent, clone, model.getChildCount(parent)); - - var other = model.getTerminal(edge, !isSource); - this.graph.connectCell(clone, other, !isSource); - - edge = clone; - } - - var constraint = this.constraintHandler.currentConstraint; - - if (constraint == null) - { - constraint = new mxConnectionConstraint(); - } - - this.graph.connectCell(edge, terminal, isSource, constraint); - } - finally - { - model.endUpdate(); - } - - return edge; -}; - -/** - * Function: changeTerminalPoint - * - * Changes the terminal point of the given edge. - */ -mxEdgeHandler.prototype.changeTerminalPoint = function(edge, point, isSource) -{ - var model = this.graph.getModel(); - var geo = model.getGeometry(edge); - - if (geo != null) - { - model.beginUpdate(); - try - { - geo = geo.clone(); - geo.setTerminalPoint(point, isSource); - model.setGeometry(edge, geo); - this.graph.connectCell(edge, null, isSource, new mxConnectionConstraint()); - } - finally - { - model.endUpdate(); - } - } -}; - -/** - * Function: changePoints - * - * Changes the control points of the given edge in the graph model. - */ -mxEdgeHandler.prototype.changePoints = function(edge, points) -{ - var model = this.graph.getModel(); - var geo = model.getGeometry(edge); - - if (geo != null) - { - geo = geo.clone(); - geo.points = points; - - model.setGeometry(edge, geo); - } -}; - -/** - * Function: addPoint - * - * Adds a control point for the given state and event. - */ -mxEdgeHandler.prototype.addPoint = function(state, evt) -{ - var geo = this.graph.getCellGeometry(state.cell); - - if (geo != null) - { - geo = geo.clone(); - var pt = mxUtils.convertPoint(this.graph.container, mxEvent.getClientX(evt), - mxEvent.getClientY(evt)); - var index = mxUtils.findNearestSegment(state, pt.x, pt.y); - var gridEnabled = this.graph.isGridEnabledEvent(evt); - this.convertPoint(pt, gridEnabled); - - if (geo.points == null) - { - geo.points = [pt]; - } - else - { - geo.points.splice(index, 0, pt); - } - - this.graph.getModel().setGeometry(state.cell, geo); - this.destroy(); - this.init(); - mxEvent.consume(evt); - } -}; - -/** - * Function: removePoint - * - * Removes the control point at the given index from the given state. - */ -mxEdgeHandler.prototype.removePoint = function(state, index) -{ - if (index > 0 && index < this.abspoints.length - 1) - { - var geo = this.graph.getCellGeometry(this.state.cell); - - if (geo != null && - geo.points != null) - { - geo = geo.clone(); - geo.points.splice(index - 1, 1); - this.graph.getModel().setGeometry(state.cell, geo); - this.destroy(); - this.init(); - } - } -}; - -/** - * Function: getHandleFillColor - * - * Returns the fillcolor for the handle at the given index. - */ -mxEdgeHandler.prototype.getHandleFillColor = function(index) -{ - var isSource = index == 0; - var cell = this.state.cell; - var terminal = this.graph.getModel().getTerminal(cell, isSource); - var color = mxConstants.HANDLE_FILLCOLOR; - - if ((terminal != null && !this.graph.isCellDisconnectable(cell, terminal, isSource)) || - (terminal == null && !this.graph.isTerminalPointMovable(cell, isSource))) - { - color = mxConstants.LOCKED_HANDLE_FILLCOLOR; - } - else if (terminal != null && this.graph.isCellDisconnectable(cell, terminal, isSource)) - { - color = mxConstants.CONNECT_HANDLE_FILLCOLOR; - } - - return color; -}; - -/** - * Function: redraw - * - * Redraws the preview, and the bends- and label control points. - */ -mxEdgeHandler.prototype.redraw = function() -{ - this.abspoints = this.state.absolutePoints.slice(); - var cell = this.state.cell; - - // Updates the handle for the label position - var s = mxConstants.LABEL_HANDLE_SIZE; - - this.label = new mxPoint(this.state.absoluteOffset.x, this.state.absoluteOffset.y); - this.labelShape.bounds = new mxRectangle(this.label.x - s / 2, - this.label.y - s / 2, s, s); - this.labelShape.redraw(); - - // Shows or hides the label handle depending on the label - var lab = this.graph.getLabel(cell); - - if (lab != null && lab.length > 0 && this.graph.isLabelMovable(cell)) - { - this.labelShape.node.style.visibility = 'visible'; - } - else - { - this.labelShape.node.style.visibility = 'hidden'; - } - - if (this.bends != null && this.bends.length > 0) - { - var n = this.abspoints.length - 1; - - var p0 = this.abspoints[0]; - var x0 = this.abspoints[0].x; - var y0 = this.abspoints[0].y; - - var b = this.bends[0].bounds; - this.bends[0].bounds = new mxRectangle(x0 - b.width / 2, y0 - b.height / 2, b.width, b.height); - this.bends[0].fill = this.getHandleFillColor(0); - this.bends[0].reconfigure(); - this.bends[0].redraw(); - - var pe = this.abspoints[n]; - var xn = this.abspoints[n].x; - var yn = this.abspoints[n].y; - - var bn = this.bends.length - 1; - b = this.bends[bn].bounds; - this.bends[bn].bounds = new mxRectangle(xn - b.width / 2, yn - b.height / 2, b.width, b.height); - this.bends[bn].fill = this.getHandleFillColor(bn); - this.bends[bn].reconfigure(); - this.bends[bn].redraw(); - - this.redrawInnerBends(p0, pe); - } - - this.drawPreview(); -}; - -/** - * Function: redrawInnerBends - * - * Updates and redraws the inner bends. - * - * Parameters: - * - * p0 - that represents the location of the first point. - * pe - that represents the location of the last point. - */ -mxEdgeHandler.prototype.redrawInnerBends = function(p0, pe) -{ - var g = this.graph.getModel().getGeometry(this.state.cell); - var pts = g.points; - - if (pts != null) - { - if (this.points == null) - { - this.points = []; - } - - for (var i = 1; i < this.bends.length-1; i++) - { - if (this.bends[i] != null) - { - if (this.abspoints[i] != null) - { - var x = this.abspoints[i].x; - var y = this.abspoints[i].y; - - var b = this.bends[i].bounds; - this.bends[i].node.style.visibility = 'visible'; - this.bends[i].bounds = new mxRectangle(x - b.width / 2, y - b.height / 2, b.width, b.height); - this.bends[i].redraw(); - - this.points[i - 1] = pts[i - 1]; - } - else - { - this.bends[i].destroy(); - this.bends[i] = null; - } - } - } - } -}; - -/** - * Function: drawPreview - * - * Redraws the preview. - */ -mxEdgeHandler.prototype.drawPreview = function() -{ - if (this.isLabel) - { - var s = mxConstants.LABEL_HANDLE_SIZE; - - var bounds = new mxRectangle(this.label.x - s / 2, this.label.y - s / 2, s, s); - this.labelShape.bounds = bounds; - this.labelShape.redraw(); - } - else - { - this.shape.points = this.abspoints; - this.shape.redraw(); - } - - // Workaround to force a repaint in AppleWebKit - mxUtils.repaintGraph(this.graph, this.shape.points[this.shape.points.length - 1]); -}; - -/** - * Function: destroy - * - * Destroys the handler and all its resources and DOM nodes. This does - * normally not need to be called as handlers are destroyed automatically - * when the corresponding cell is deselected. - */ -mxEdgeHandler.prototype.destroy = function() -{ - if (this.marker != null) - { - this.marker.destroy(); - this.marker = null; - } - - if (this.shape != null) - { - this.shape.destroy(); - this.shape = null; - } - - if (this.labelShape != null) - { - this.labelShape.destroy(); - this.labelShape = null; - } - - if (this.constraintHandler != null) - { - this.constraintHandler.destroy(); - this.constraintHandler = null; - } - - // Destroy the control points for the bends - if (this.bends != null) - { - for (var i = 0; i < this.bends.length; i++) - { - if (this.bends[i] != null) - { - this.bends[i].destroy(); - this.bends[i] = null; - } - } - } -}; diff --git a/src/js/handler/mxEdgeSegmentHandler.js b/src/js/handler/mxEdgeSegmentHandler.js deleted file mode 100644 index e14fde0..0000000 --- a/src/js/handler/mxEdgeSegmentHandler.js +++ /dev/null @@ -1,284 +0,0 @@ -/** - * $Id: mxEdgeSegmentHandler.js,v 1.14 2012-12-17 13:22:49 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -function mxEdgeSegmentHandler(state) -{ - if (state != null) - { - this.state = state; - this.init(); - } -}; - -/** - * Extends mxEdgeHandler. - */ -mxEdgeSegmentHandler.prototype = new mxElbowEdgeHandler(); -mxEdgeSegmentHandler.prototype.constructor = mxEdgeSegmentHandler; - -/** - * Function: getPreviewPoints - * - * Updates the given preview state taking into account the state of the constraint handler. - */ -mxEdgeSegmentHandler.prototype.getPreviewPoints = function(point) -{ - if (this.isSource || this.isTarget) - { - return mxElbowEdgeHandler.prototype.getPreviewPoints.apply(this, arguments); - } - else - { - this.convertPoint(point, false); - var pts = this.state.absolutePoints; - var last = pts[0].clone(); - this.convertPoint(last, false); - var result = []; - - for (var i = 1; i < pts.length; i++) - { - var pt = pts[i].clone(); - this.convertPoint(pt, false); - - if (i == this.index) - { - if (last.x == pt.x) - { - last.x = point.x; - pt.x = point.x; - } - else - { - last.y = point.y; - pt.y = point.y; - } - } - - if (i < pts.length - 1) - { - result.push(pt); - } - - last = pt; - } - - if (result.length == 1) - { - var view = this.state.view; - var source = this.state.getVisibleTerminalState(true); - var target = this.state.getVisibleTerminalState(false); - - if (target != null & source != null) - { - var dx = this.state.origin.x; - var dy = this.state.origin.y; - - if (mxUtils.contains(target, result[0].x + dx, result[0].y + dy)) - { - if (pts[1].y == pts[2].y) - { - result[0].y = view.getRoutingCenterY(source) - dy; - } - else - { - result[0].x = view.getRoutingCenterX(source) - dx; - } - } - else if (mxUtils.contains(source, result[0].x + dx, result[0].y + dy)) - { - if (pts[1].y == pts[0].y) - { - result[0].y = view.getRoutingCenterY(target) - dy; - } - else - { - result[0].x = view.getRoutingCenterX(target) - dx; - } - } - } - } - else if (result.length == 0) - { - result = [point]; - } - - return result; - } -}; - -/** - * Function: createBends - * - * Adds custom bends for the center of each segment. - */ -mxEdgeSegmentHandler.prototype.createBends = function() -{ - var bends = []; - - // Source - var bend = this.createHandleShape(0); - - this.initBend(bend); - bend.node.style.cursor = mxConstants.CURSOR_BEND_HANDLE; - mxEvent.redirectMouseEvents(bend.node, this.graph, this.state); - bends.push(bend); - - if (mxClient.IS_TOUCH) - { - bend.node.setAttribute('pointer-events', 'none'); - } - - var pts = this.state.absolutePoints; - - // Waypoints (segment handles) - if (this.graph.isCellBendable(this.state.cell)) - { - if (this.points == null) - { - this.points = []; - } - - for (var i = 0; i < pts.length - 1; i++) - { - var bend = this.createVirtualBend(); - bends.push(bend); - var horizontal = pts[i].x - pts[i + 1].x == 0; - bend.node.style.cursor = (horizontal) ? 'col-resize' : 'row-resize'; - this.points.push(new mxPoint(0,0)); - - if (mxClient.IS_TOUCH) - { - bend.node.setAttribute('pointer-events', 'none'); - } - } - } - - // Target - var bend = this.createHandleShape(pts.length); - - this.initBend(bend); - bend.node.style.cursor = mxConstants.CURSOR_BEND_HANDLE; - mxEvent.redirectMouseEvents(bend.node, this.graph, this.state); - bends.push(bend); - - if (mxClient.IS_TOUCH) - { - bend.node.setAttribute('pointer-events', 'none'); - } - - return bends; -}; - - -/** - * Function: redrawInnerBends - * - * Updates the position of the custom bends. - */ -mxEdgeSegmentHandler.prototype.redrawInnerBends = function(p0, pe) -{ - if (this.graph.isCellBendable(this.state.cell)) - { - var s = mxConstants.HANDLE_SIZE; - var pts = this.state.absolutePoints; - - if (pts != null && pts.length > 1) - { - for (var i = 0; i < this.state.absolutePoints.length - 1; i++) - { - if (this.bends[i + 1] != null) - { - var p0 = pts[i]; - var pe = pts[i + 1]; - var pt = new mxPoint(p0.x + (pe.x - p0.x) / 2, p0.y + (pe.y - p0.y) / 2); - this.bends[i+1].bounds = new mxRectangle(pt.x - s / 2, pt.y - s / 2, s, s); - this.bends[i+1].reconfigure(); - this.bends[i+1].redraw(); - } - } - } - } -}; - -/** - * Function: connect - * - * Calls after . - */ -mxEdgeSegmentHandler.prototype.connect = function(edge, terminal, isSource, isClone, me) -{ - mxEdgeHandler.prototype.connect.apply(this, arguments); - this.refresh(); -}; - -/** - * Function: changeTerminalPoint - * - * Calls after . - */ -mxEdgeSegmentHandler.prototype.changeTerminalPoint = function(edge, point, isSource) -{ - mxEdgeHandler.prototype.changeTerminalPoint.apply(this, arguments); - this.refresh(); -}; - -/** - * Function: changePoints - * - * Changes the points of the given edge to reflect the current state of the handler. - */ -mxEdgeSegmentHandler.prototype.changePoints = function(edge, points) -{ - points = []; - var pts = this.abspoints; - - if (pts.length > 1) - { - var pt0 = pts[0]; - var pt1 = pts[1]; - - for (var i = 2; i < pts.length; i++) - { - var pt2 = pts[i]; - - if ((Math.round(pt0.x) != Math.round(pt1.x) || - Math.round(pt1.x) != Math.round(pt2.x)) && - (Math.round(pt0.y) != Math.round(pt1.y) || - Math.round(pt1.y) != Math.round(pt2.y))) - { - pt0 = pt1; - pt1 = pt1.clone(); - this.convertPoint(pt1, false); - points.push(pt1); - } - - pt1 = pt2; - } - } - - mxElbowEdgeHandler.prototype.changePoints.apply(this, arguments); - this.refresh(); -}; - -/** - * Function: refresh - * - * Refreshes the bends of this handler. - */ -mxEdgeSegmentHandler.prototype.refresh = function() -{ - if (this.bends != null) - { - for (var i = 0; i < this.bends.length; i++) - { - if (this.bends[i] != null) - { - this.bends[i].destroy(); - this.bends[i] = null; - } - } - - this.bends = this.createBends(); - } -}; diff --git a/src/js/handler/mxElbowEdgeHandler.js b/src/js/handler/mxElbowEdgeHandler.js deleted file mode 100644 index 85fbb06..0000000 --- a/src/js/handler/mxElbowEdgeHandler.js +++ /dev/null @@ -1,248 +0,0 @@ -/** - * $Id: mxElbowEdgeHandler.js,v 1.43 2012-01-06 13:06:01 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxElbowEdgeHandler - * - * Graph event handler that reconnects edges and modifies control points and - * the edge label location. Uses for finding and - * highlighting new source and target vertices. This handler is automatically - * created in . It extends . - * - * Constructor: mxEdgeHandler - * - * Constructs an edge handler for the specified . - * - * Parameters: - * - * state - of the cell to be modified. - */ -function mxElbowEdgeHandler(state) -{ - if (state != null) - { - this.state = state; - this.init(); - } -}; - -/** - * Extends mxEdgeHandler. - */ -mxElbowEdgeHandler.prototype = new mxEdgeHandler(); -mxElbowEdgeHandler.prototype.constructor = mxElbowEdgeHandler; - -/** - * Specifies if a double click on the middle handle should call - * . Default is true. - */ -mxElbowEdgeHandler.prototype.flipEnabled = true; - -/** - * Variable: doubleClickOrientationResource - * - * Specifies the resource key for the tooltip to be displayed on the single - * control point for routed edges. If the resource for this key does not - * exist then the value is used as the error message. Default is - * 'doubleClickOrientation'. - */ -mxElbowEdgeHandler.prototype.doubleClickOrientationResource = - (mxClient.language != 'none') ? 'doubleClickOrientation' : ''; - -/** - * Function: createBends - * - * Overrides to create custom bends. - */ - mxElbowEdgeHandler.prototype.createBends = function() - { - var bends = []; - - // Source - var bend = this.createHandleShape(0); - - this.initBend(bend); - bend.node.style.cursor = mxConstants.CURSOR_BEND_HANDLE; - mxEvent.redirectMouseEvents(bend.node, this.graph, this.state); - bends.push(bend); - - if (mxClient.IS_TOUCH) - { - bend.node.setAttribute('pointer-events', 'none'); - } - - // Virtual - bends.push(this.createVirtualBend()); - this.points.push(new mxPoint(0,0)); - - // Target - bend = this.createHandleShape(2); - - this.initBend(bend); - bend.node.style.cursor = mxConstants.CURSOR_BEND_HANDLE; - mxEvent.redirectMouseEvents(bend.node, this.graph, this.state); - bends.push(bend); - - if (mxClient.IS_TOUCH) - { - bend.node.setAttribute('pointer-events', 'none'); - } - - return bends; - }; - -/** - * Function: createVirtualBend - * - * Creates a virtual bend that supports double clicking and calls - * . - */ -mxElbowEdgeHandler.prototype.createVirtualBend = function() -{ - var bend = this.createHandleShape(); - this.initBend(bend); - - var crs = this.getCursorForBend(); - bend.node.style.cursor = crs; - - // Double-click changes edge style - var dblClick = mxUtils.bind(this, function(evt) - { - if (!mxEvent.isConsumed(evt) && - this.flipEnabled) - { - this.graph.flipEdge(this.state.cell, evt); - mxEvent.consume(evt); - } - }); - - mxEvent.redirectMouseEvents(bend.node, this.graph, this.state, - null, null, null, dblClick); - - if (!this.graph.isCellBendable(this.state.cell)) - { - bend.node.style.visibility = 'hidden'; - } - - return bend; -}; - -/** - * Function: getCursorForBend - * - * Returns the cursor to be used for the bend. - */ -mxElbowEdgeHandler.prototype.getCursorForBend = function() -{ - return (this.state.style[mxConstants.STYLE_EDGE] == mxEdgeStyle.TopToBottom || - this.state.style[mxConstants.STYLE_EDGE] == mxConstants.EDGESTYLE_TOPTOBOTTOM || - ((this.state.style[mxConstants.STYLE_EDGE] == mxEdgeStyle.ElbowConnector || - this.state.style[mxConstants.STYLE_EDGE] == mxConstants.EDGESTYLE_ELBOW)&& - this.state.style[mxConstants.STYLE_ELBOW] == mxConstants.ELBOW_VERTICAL)) ? - 'row-resize' : 'col-resize'; -}; - -/** - * Function: getTooltipForNode - * - * Returns the tooltip for the given node. - */ -mxElbowEdgeHandler.prototype.getTooltipForNode = function(node) -{ - var tip = null; - - if (this.bends != null && - this.bends[1] != null && - (node == this.bends[1].node || - node.parentNode == this.bends[1].node)) - { - tip = this.doubleClickOrientationResource; - tip = mxResources.get(tip) || tip; // translate - } - - return tip; -}; - -/** - * Function: convertPoint - * - * Converts the given point in-place from screen to unscaled, untranslated - * graph coordinates and applies the grid. - * - * Parameters: - * - * point - to be converted. - * gridEnabled - Boolean that specifies if the grid should be applied. - */ -mxElbowEdgeHandler.prototype.convertPoint = function(point, gridEnabled) -{ - var scale = this.graph.getView().getScale(); - var tr = this.graph.getView().getTranslate(); - var origin = this.state.origin; - - if (gridEnabled) - { - point.x = this.graph.snap(point.x); - point.y = this.graph.snap(point.y); - } - - point.x = Math.round(point.x / scale - tr.x - origin.x); - point.y = Math.round(point.y / scale - tr.y - origin.y); -}; - -/** - * Function: redrawInnerBends - * - * Updates and redraws the inner bends. - * - * Parameters: - * - * p0 - that represents the location of the first point. - * pe - that represents the location of the last point. - */ -mxElbowEdgeHandler.prototype.redrawInnerBends = function(p0, pe) -{ - var g = this.graph.getModel().getGeometry(this.state.cell); - var pts = g.points; - - var pt = (pts != null) ? pts[0] : null; - - if (pt == null) - { - pt = new mxPoint(p0.x + (pe.x - p0.x) / 2, p0.y + (pe.y - p0.y) / 2); - } - else - { - pt = new mxPoint(this.graph.getView().scale*(pt.x + - this.graph.getView().translate.x + this.state.origin.x), - this.graph.getView().scale*(pt.y + this.graph.getView().translate.y + - this.state.origin.y)); - } - - // Makes handle slightly bigger if the yellow label handle - // exists and intersects this green handle - var b = this.bends[1].bounds; - var w = b.width; - var h = b.height; - - if (this.handleImage == null) - { - w = mxConstants.HANDLE_SIZE; - h = mxConstants.HANDLE_SIZE; - } - - var bounds = new mxRectangle(pt.x - w / 2, pt.y - h / 2, w, h); - - if (this.handleImage == null && this.labelShape.node.style.visibility != 'hidden' && - mxUtils.intersects(bounds, this.labelShape.bounds)) - { - w += 3; - h += 3; - bounds = new mxRectangle(pt.x - w / 2, pt.y - h / 2, w, h); - } - - this.bends[1].bounds = bounds; - this.bends[1].reconfigure(); - this.bends[1].redraw(); -}; diff --git a/src/js/handler/mxGraphHandler.js b/src/js/handler/mxGraphHandler.js deleted file mode 100644 index 57e27a1..0000000 --- a/src/js/handler/mxGraphHandler.js +++ /dev/null @@ -1,916 +0,0 @@ -/** - * $Id: mxGraphHandler.js,v 1.129 2012-04-13 12:53:30 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxGraphHandler - * - * Graph event handler that handles selection. Individual cells are handled - * separately using or one of the edge handlers. These - * handlers are created using in - * . - * - * To avoid the container to scroll a moved cell into view, set - * to false. - * - * Constructor: mxGraphHandler - * - * Constructs an event handler that creates handles for the - * selection cells. - * - * Parameters: - * - * graph - Reference to the enclosing . - */ -function mxGraphHandler(graph) -{ - this.graph = graph; - this.graph.addMouseListener(this); - - // Repaints the handler after autoscroll - this.panHandler = mxUtils.bind(this, function() - { - this.updatePreviewShape(); - }); - - this.graph.addListener(mxEvent.PAN, this.panHandler); -}; - -/** - * Variable: graph - * - * Reference to the enclosing . - */ -mxGraphHandler.prototype.graph = null; - -/** - * Variable: maxCells - * - * Defines the maximum number of cells to paint subhandles - * for. Default is 50 for Firefox and 20 for IE. Set this - * to 0 if you want an unlimited number of handles to be - * displayed. This is only recommended if the number of - * cells in the graph is limited to a small number, eg. - * 500. - */ -mxGraphHandler.prototype.maxCells = (mxClient.IS_IE) ? 20 : 50; - -/** - * Variable: enabled - * - * Specifies if events are handled. Default is true. - */ -mxGraphHandler.prototype.enabled = true; - -/** - * Variable: highlightEnabled - * - * Specifies if drop targets under the mouse should be enabled. Default is - * true. - */ -mxGraphHandler.prototype.highlightEnabled = true; - -/** - * Variable: cloneEnabled - * - * Specifies if cloning by control-drag is enabled. Default is true. - */ -mxGraphHandler.prototype.cloneEnabled = true; - -/** - * Variable: moveEnabled - * - * Specifies if moving is enabled. Default is true. - */ -mxGraphHandler.prototype.moveEnabled = true; - -/** - * Variable: guidesEnabled - * - * Specifies if other cells should be used for snapping the right, center or - * left side of the current selection. Default is false. - */ -mxGraphHandler.prototype.guidesEnabled = false; - -/** - * Variable: guide - * - * Holds the instance that is used for alignment. - */ -mxGraphHandler.prototype.guide = null; - -/** - * Variable: currentDx - * - * Stores the x-coordinate of the current mouse move. - */ -mxGraphHandler.prototype.currentDx = null; - -/** - * Variable: currentDy - * - * Stores the y-coordinate of the current mouse move. - */ -mxGraphHandler.prototype.currentDy = null; - -/** - * Variable: updateCursor - * - * Specifies if a move cursor should be shown if the mouse is ove a movable - * cell. Default is true. - */ -mxGraphHandler.prototype.updateCursor = true; - -/** - * Variable: selectEnabled - * - * Specifies if selecting is enabled. Default is true. - */ -mxGraphHandler.prototype.selectEnabled = true; - -/** - * Variable: removeCellsFromParent - * - * Specifies if cells may be moved out of their parents. Default is true. - */ -mxGraphHandler.prototype.removeCellsFromParent = true; - -/** - * Variable: connectOnDrop - * - * Specifies if drop events are interpreted as new connections if no other - * drop action is defined. Default is false. - */ -mxGraphHandler.prototype.connectOnDrop = false; - -/** - * Variable: scrollOnMove - * - * Specifies if the view should be scrolled so that a moved cell is - * visible. Default is true. - */ -mxGraphHandler.prototype.scrollOnMove = true; - -/** - * Variable: minimumSize - * - * Specifies the minimum number of pixels for the width and height of a - * selection border. Default is 6. - */ -mxGraphHandler.prototype.minimumSize = 6; - -/** - * Variable: previewColor - * - * Specifies the color of the preview shape. Default is black. - */ -mxGraphHandler.prototype.previewColor = 'black'; - -/** - * Variable: htmlPreview - * - * Specifies if the graph container should be used for preview. If this is used - * then drop target detection relies entirely on because - * the HTML preview does not "let events through". Default is false. - */ -mxGraphHandler.prototype.htmlPreview = false; - -/** - * Variable: shape - * - * Reference to the that represents the preview. - */ -mxGraphHandler.prototype.shape = null; - -/** - * Variable: scaleGrid - * - * Specifies if the grid should be scaled. Default is false. - */ -mxGraphHandler.prototype.scaleGrid = false; - -/** - * Variable: crisp - * - * Specifies if the move preview should be rendered in crisp mode if applicable. - * Default is true. - */ -mxGraphHandler.prototype.crisp = true; - -/** - * Function: isEnabled - * - * Returns . - */ -mxGraphHandler.prototype.isEnabled = function() -{ - return this.enabled; -}; - -/** - * Function: setEnabled - * - * Sets . - */ -mxGraphHandler.prototype.setEnabled = function(value) -{ - this.enabled = value; -}; - -/** - * Function: isCloneEnabled - * - * Returns . - */ -mxGraphHandler.prototype.isCloneEnabled = function() -{ - return this.cloneEnabled; -}; - -/** - * Function: setCloneEnabled - * - * Sets . - * - * Parameters: - * - * value - Boolean that specifies the new clone enabled state. - */ -mxGraphHandler.prototype.setCloneEnabled = function(value) -{ - this.cloneEnabled = value; -}; - -/** - * Function: isMoveEnabled - * - * Returns . - */ -mxGraphHandler.prototype.isMoveEnabled = function() -{ - return this.moveEnabled; -}; - -/** - * Function: setMoveEnabled - * - * Sets . - */ -mxGraphHandler.prototype.setMoveEnabled = function(value) -{ - this.moveEnabled = value; -}; - -/** - * Function: isSelectEnabled - * - * Returns . - */ -mxGraphHandler.prototype.isSelectEnabled = function() -{ - return this.selectEnabled; -}; - -/** - * Function: setSelectEnabled - * - * Sets . - */ -mxGraphHandler.prototype.setSelectEnabled = function(value) -{ - this.selectEnabled = value; -}; - -/** - * Function: isRemoveCellsFromParent - * - * Returns . - */ -mxGraphHandler.prototype.isRemoveCellsFromParent = function() -{ - return this.removeCellsFromParent; -}; - -/** - * Function: setRemoveCellsFromParent - * - * Sets . - */ -mxGraphHandler.prototype.setRemoveCellsFromParent = function(value) -{ - this.removeCellsFromParent = value; -}; - -/** - * Function: getInitialCellForEvent - * - * Hook to return initial cell for the given event. - */ -mxGraphHandler.prototype.getInitialCellForEvent = function(me) -{ - return me.getCell(); -}; - -/** - * Function: isDelayedSelection - * - * Hook to return true for delayed selections. - */ -mxGraphHandler.prototype.isDelayedSelection = function(cell) -{ - return this.graph.isCellSelected(cell); -}; - -/** - * Function: mouseDown - * - * Handles the event by selecing the given cell and creating a handle for - * it. By consuming the event all subsequent events of the gesture are - * redirected to this handler. - */ -mxGraphHandler.prototype.mouseDown = function(sender, me) -{ - if (!me.isConsumed() && this.isEnabled() && this.graph.isEnabled() && - !this.graph.isForceMarqueeEvent(me.getEvent()) && me.getState() != null) - { - var cell = this.getInitialCellForEvent(me); - this.cell = null; - this.delayedSelection = this.isDelayedSelection(cell); - - if (this.isSelectEnabled() && !this.delayedSelection) - { - this.graph.selectCellForEvent(cell, me.getEvent()); - } - - if (this.isMoveEnabled()) - { - var model = this.graph.model; - var geo = model.getGeometry(cell); - - if (this.graph.isCellMovable(cell) && ((!model.isEdge(cell) || this.graph.getSelectionCount() > 1 || - (geo.points != null && geo.points.length > 0) || model.getTerminal(cell, true) == null || - model.getTerminal(cell, false) == null) || this.graph.allowDanglingEdges || - (this.graph.isCloneEvent(me.getEvent()) && this.graph.isCellsCloneable()))) - { - this.start(cell, me.getX(), me.getY()); - } - - this.cellWasClicked = true; - - // Workaround for SELECT element not working in Webkit, this blocks moving - // of the cell if the select element is clicked in Safari which is needed - // because Safari doesn't seem to route the subsequent mouseUp event via - // this handler which leads to an inconsistent state (no reset called). - // Same for cellWasClicked which will block clearing the selection when - // clicking the background after clicking on the SELECT element in Safari. - if ((!mxClient.IS_SF && !mxClient.IS_GC) || me.getSource().nodeName != 'SELECT') - { - me.consume(); - } - else if (mxClient.IS_SF && me.getSource().nodeName == 'SELECT') - { - this.cellWasClicked = false; - this.first = null; - } - } - } -}; - -/** - * Function: getGuideStates - * - * Creates an array of cell states which should be used as guides. - */ -mxGraphHandler.prototype.getGuideStates = function() -{ - var parent = this.graph.getDefaultParent(); - var model = this.graph.getModel(); - - var filter = mxUtils.bind(this, function(cell) - { - return this.graph.view.getState(cell) != null && - model.isVertex(cell) && - model.getGeometry(cell) != null && - !model.getGeometry(cell).relative; - }); - - return this.graph.view.getCellStates(model.filterDescendants(filter, parent)); -}; - -/** - * Function: getCells - * - * Returns the cells to be modified by this handler. This implementation - * returns all selection cells that are movable, or the given initial cell if - * the given cell is not selected and movable. This handles the case of moving - * unselectable or unselected cells. - * - * Parameters: - * - * initialCell - that triggered this handler. - */ -mxGraphHandler.prototype.getCells = function(initialCell) -{ - if (!this.delayedSelection && this.graph.isCellMovable(initialCell)) - { - return [initialCell]; - } - else - { - return this.graph.getMovableCells(this.graph.getSelectionCells()); - } -}; - -/** - * Function: getPreviewBounds - * - * Returns the used as the preview bounds for - * moving the given cells. - */ -mxGraphHandler.prototype.getPreviewBounds = function(cells) -{ - var bounds = this.graph.getView().getBounds(cells); - - if (bounds != null) - { - if (bounds.width < this.minimumSize) - { - var dx = this.minimumSize - bounds.width; - bounds.x -= dx / 2; - bounds.width = this.minimumSize; - } - - if (bounds.height < this.minimumSize) - { - var dy = this.minimumSize - bounds.height; - bounds.y -= dy / 2; - bounds.height = this.minimumSize; - } - } - - return bounds; -}; - -/** - * Function: createPreviewShape - * - * Creates the shape used to draw the preview for the given bounds. - */ -mxGraphHandler.prototype.createPreviewShape = function(bounds) -{ - var shape = new mxRectangleShape(bounds, null, this.previewColor); - shape.isDashed = true; - shape.crisp = this.crisp; - - if (this.htmlPreview) - { - shape.dialect = mxConstants.DIALECT_STRICTHTML; - shape.init(this.graph.container); - } - else - { - // Makes sure to use either VML or SVG shapes in order to implement - // event-transparency on the background area of the rectangle since - // HTML shapes do not let mouseevents through even when transparent - shape.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? - mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG; - shape.init(this.graph.getView().getOverlayPane()); - - // Event-transparency - if (shape.dialect == mxConstants.DIALECT_SVG) - { - shape.node.setAttribute('style', 'pointer-events:none;'); - } - else - { - shape.node.style.background = ''; - } - } - - return shape; -}; - -/** - * Function: start - * - * Starts the handling of the mouse gesture. - */ -mxGraphHandler.prototype.start = function(cell, x, y) -{ - this.cell = cell; - this.first = mxUtils.convertPoint(this.graph.container, x, y); - this.cells = this.getCells(this.cell); - this.bounds = this.getPreviewBounds(this.cells); - - if (this.guidesEnabled) - { - this.guide = new mxGuide(this.graph, this.getGuideStates()); - } -}; - -/** - * Function: useGuidesForEvent - * - * Returns true if the guides should be used for the given . - * This implementation returns . - */ -mxGraphHandler.prototype.useGuidesForEvent = function(me) -{ - return (this.guide != null) ? this.guide.isEnabledForEvent(me.getEvent()) : true; -}; - - -/** - * Function: snap - * - * Snaps the given vector to the grid and returns the given mxPoint instance. - */ -mxGraphHandler.prototype.snap = function(vector) -{ - var scale = (this.scaleGrid) ? this.graph.view.scale : 1; - - vector.x = this.graph.snap(vector.x / scale) * scale; - vector.y = this.graph.snap(vector.y / scale) * scale; - - return vector; -}; - -/** - * Function: mouseMove - * - * Handles the event by highlighting possible drop targets and updating the - * preview. - */ -mxGraphHandler.prototype.mouseMove = function(sender, me) -{ - var graph = this.graph; - - if (!me.isConsumed() && graph.isMouseDown && this.cell != null && - this.first != null && this.bounds != null) - { - var point = mxUtils.convertPoint(graph.container, me.getX(), me.getY()); - var dx = point.x - this.first.x; - var dy = point.y - this.first.y; - var tol = graph.tolerance; - - if (this.shape!= null || Math.abs(dx) > tol || Math.abs(dy) > tol) - { - // Highlight is used for highlighting drop targets - if (this.highlight == null) - { - this.highlight = new mxCellHighlight(this.graph, - mxConstants.DROP_TARGET_COLOR, 3); - } - - if (this.shape == null) - { - this.shape = this.createPreviewShape(this.bounds); - } - - var gridEnabled = graph.isGridEnabledEvent(me.getEvent()); - var hideGuide = true; - - if (this.guide != null && this.useGuidesForEvent(me)) - { - var delta = this.guide.move(this.bounds, new mxPoint(dx, dy), gridEnabled); - hideGuide = false; - dx = delta.x; - dy = delta.y; - } - else if (gridEnabled) - { - var trx = graph.getView().translate; - var scale = graph.getView().scale; - - var tx = this.bounds.x - (graph.snap(this.bounds.x / scale - trx.x) + trx.x) * scale; - var ty = this.bounds.y - (graph.snap(this.bounds.y / scale - trx.y) + trx.y) * scale; - var v = this.snap(new mxPoint(dx, dy)); - - dx = v.x - tx; - dy = v.y - ty; - } - - if (this.guide != null && hideGuide) - { - this.guide.hide(); - } - - // Constrained movement if shift key is pressed - if (graph.isConstrainedEvent(me.getEvent())) - { - if (Math.abs(dx) > Math.abs(dy)) - { - dy = 0; - } - else - { - dx = 0; - } - } - - this.currentDx = dx; - this.currentDy = dy; - this.updatePreviewShape(); - - var target = null; - var cell = me.getCell(); - - if (graph.isDropEnabled() && this.highlightEnabled) - { - // Contains a call to getCellAt to find the cell under the mouse - target = graph.getDropTarget(this.cells, me.getEvent(), cell); - } - - // Checks if parent is dropped into child - var parent = target; - var model = graph.getModel(); - - while (parent != null && parent != this.cells[0]) - { - parent = model.getParent(parent); - } - - var clone = graph.isCloneEvent(me.getEvent()) && graph.isCellsCloneable() && this.isCloneEnabled(); - var state = graph.getView().getState(target); - var highlight = false; - - if (state != null && parent == null && (model.getParent(this.cell) != target || clone)) - { - if (this.target != target) - { - this.target = target; - this.setHighlightColor(mxConstants.DROP_TARGET_COLOR); - } - - highlight = true; - } - else - { - this.target = null; - - if (this.connectOnDrop && cell != null && this.cells.length == 1 && - graph.getModel().isVertex(cell) && graph.isCellConnectable(cell)) - { - state = graph.getView().getState(cell); - - if (state != null) - { - var error = graph.getEdgeValidationError(null, this.cell, cell); - var color = (error == null) ? - mxConstants.VALID_COLOR : - mxConstants.INVALID_CONNECT_TARGET_COLOR; - this.setHighlightColor(color); - highlight = true; - } - } - } - - if (state != null && highlight) - { - this.highlight.highlight(state); - } - else - { - this.highlight.hide(); - } - } - - me.consume(); - - // Cancels the bubbling of events to the container so - // that the droptarget is not reset due to an mouseMove - // fired on the container with no associated state. - mxEvent.consume(me.getEvent()); - } - else if ((this.isMoveEnabled() || this.isCloneEnabled()) && this.updateCursor && - !me.isConsumed() && me.getState() != null && !graph.isMouseDown) - { - var cursor = graph.getCursorForCell(me.getCell()); - - if (cursor == null && graph.isEnabled() && graph.isCellMovable(me.getCell())) - { - if (graph.getModel().isEdge(me.getCell())) - { - cursor = mxConstants.CURSOR_MOVABLE_EDGE; - } - else - { - cursor = mxConstants.CURSOR_MOVABLE_VERTEX; - } - } - - me.getState().setCursor(cursor); - me.consume(); - } -}; - -/** - * Function: updatePreviewShape - * - * Updates the bounds of the preview shape. - */ -mxGraphHandler.prototype.updatePreviewShape = function() -{ - if (this.shape != null) - { - this.shape.bounds = new mxRectangle(this.bounds.x + this.currentDx - this.graph.panDx, - this.bounds.y + this.currentDy - this.graph.panDy, this.bounds.width, this.bounds.height); - this.shape.redraw(); - } -}; - -/** - * Function: setHighlightColor - * - * Sets the color of the rectangle used to highlight drop targets. - * - * Parameters: - * - * color - String that represents the new highlight color. - */ -mxGraphHandler.prototype.setHighlightColor = function(color) -{ - if (this.highlight != null) - { - this.highlight.setHighlightColor(color); - } -}; - -/** - * Function: mouseUp - * - * Handles the event by applying the changes to the selection cells. - */ -mxGraphHandler.prototype.mouseUp = function(sender, me) -{ - if (!me.isConsumed()) - { - var graph = this.graph; - - if (this.cell != null && this.first != null && this.shape != null && - this.currentDx != null && this.currentDy != null) - { - var scale = graph.getView().scale; - var clone = graph.isCloneEvent(me.getEvent()) && graph.isCellsCloneable() && this.isCloneEnabled(); - var dx = this.currentDx / scale; - var dy = this.currentDy / scale; - - var cell = me.getCell(); - - if (this.connectOnDrop && this.target == null && cell != null && graph.getModel().isVertex(cell) && - graph.isCellConnectable(cell) && graph.isEdgeValid(null, this.cell, cell)) - { - graph.connectionHandler.connect(this.cell, cell, me.getEvent()); - } - else - { - var target = this.target; - - if (graph.isSplitEnabled() && graph.isSplitTarget(target, this.cells, me.getEvent())) - { - graph.splitEdge(target, this.cells, null, dx, dy); - } - else - { - this.moveCells(this.cells, dx, dy, clone, this.target, me.getEvent()); - } - } - } - else if (this.isSelectEnabled() && this.delayedSelection && this.cell != null) - { - this.selectDelayed(me); - } - } - - // Consumes the event if a cell was initially clicked - if (this.cellWasClicked) - { - me.consume(); - } - - this.reset(); -}; - -/** - * Function: selectDelayed - * - * Implements the delayed selection for the given mouse event. - */ -mxGraphHandler.prototype.selectDelayed = function(me) -{ - this.graph.selectCellForEvent(this.cell, me.getEvent()); -}; - -/** - * Function: reset - * - * Resets the state of this handler. - */ -mxGraphHandler.prototype.reset = function() -{ - this.destroyShapes(); - this.cellWasClicked = false; - this.delayedSelection = false; - this.currentDx = null; - this.currentDy = null; - this.guides = null; - this.first = null; - this.cell = null; - this.target = null; -}; - -/** - * Function: shouldRemoveCellsFromParent - * - * Returns true if the given cells should be removed from the parent for the specified - * mousereleased event. - */ -mxGraphHandler.prototype.shouldRemoveCellsFromParent = function(parent, cells, evt) -{ - if (this.graph.getModel().isVertex(parent)) - { - var pState = this.graph.getView().getState(parent); - var pt = mxUtils.convertPoint(this.graph.container, - mxEvent.getClientX(evt), mxEvent.getClientY(evt)); - - return pState != null && !mxUtils.contains(pState, pt.x, pt.y); - } - - return false; -}; - -/** - * Function: moveCells - * - * Moves the given cells by the specified amount. - */ -mxGraphHandler.prototype.moveCells = function(cells, dx, dy, clone, target, evt) -{ - if (clone) - { - cells = this.graph.getCloneableCells(cells); - } - - // Removes cells from parent - if (target == null && this.isRemoveCellsFromParent() && - this.shouldRemoveCellsFromParent(this.graph.getModel().getParent(this.cell), cells, evt)) - { - target = this.graph.getDefaultParent(); - } - - // Passes all selected cells in order to correctly clone or move into - // the target cell. The method checks for each cell if its movable. - cells = this.graph.moveCells(cells, dx - this.graph.panDx / this.graph.view.scale, - dy - this.graph.panDy / this.graph.view.scale, clone, target, evt); - - if (this.isSelectEnabled() && this.scrollOnMove) - { - this.graph.scrollCellToVisible(cells[0]); - } - - // Selects the new cells if cells have been cloned - if (clone) - { - this.graph.setSelectionCells(cells); - } -}; - -/** - * Function: destroyShapes - * - * Destroy the preview and highlight shapes. - */ -mxGraphHandler.prototype.destroyShapes = function() -{ - // Destroys the preview dashed rectangle - if (this.shape != null) - { - this.shape.destroy(); - this.shape = null; - } - - if (this.guide != null) - { - this.guide.destroy(); - this.guide = null; - } - - // Destroys the drop target highlight - if (this.highlight != null) - { - this.highlight.destroy(); - this.highlight = null; - } -}; - -/** - * Function: destroy - * - * Destroys the handler and all its resources and DOM nodes. - */ -mxGraphHandler.prototype.destroy = function() -{ - this.graph.removeMouseListener(this); - this.graph.removeListener(this.panHandler); - this.destroyShapes(); -}; diff --git a/src/js/handler/mxKeyHandler.js b/src/js/handler/mxKeyHandler.js deleted file mode 100644 index cc07e51..0000000 --- a/src/js/handler/mxKeyHandler.js +++ /dev/null @@ -1,402 +0,0 @@ -/** - * $Id: mxKeyHandler.js,v 1.48 2012-03-30 08:30:41 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxKeyHandler - * - * Event handler that listens to keystroke events. This is not a singleton, - * however, it is normally only required once if the target is the document - * element (default). - * - * This handler installs a key event listener in the topmost DOM node and - * processes all events that originate from descandants of - * or from the topmost DOM node. The latter means that all unhandled keystrokes - * are handled by this object regardless of the focused state of the . - * - * Example: - * - * The following example creates a key handler that listens to the delete key - * (46) and deletes the selection cells if the graph is enabled. - * - * (code) - * var keyHandler = new mxKeyHandler(graph); - * keyHandler.bindKey(46, function(evt) - * { - * if (graph.isEnabled()) - * { - * graph.removeCells(); - * } - * }); - * (end) - * - * Keycodes: - * - * See http://tinyurl.com/yp8jgl or http://tinyurl.com/229yqw for a list of - * keycodes or install a key event listener into the document element and print - * the key codes of the respective events to the console. - * - * To support the Command key and the Control key on the Mac, the following - * code can be used. - * - * (code) - * keyHandler.getFunction = function(evt) - * { - * if (evt != null) - * { - * return (mxEvent.isControlDown(evt) || (mxClient.IS_MAC && evt.metaKey)) ? this.controlKeys[evt.keyCode] : this.normalKeys[evt.keyCode]; - * } - * - * return null; - * }; - * (end) - * - * Constructor: mxKeyHandler - * - * Constructs an event handler that executes functions bound to specific - * keystrokes. - * - * Parameters: - * - * graph - Reference to the associated . - * target - Optional reference to the event target. If null, the document - * element is used as the event target, that is, the object where the key - * event listener is installed. - */ -function mxKeyHandler(graph, target) -{ - if (graph != null) - { - this.graph = graph; - this.target = target || document.documentElement; - - // Creates the arrays to map from keycodes to functions - this.normalKeys = []; - this.shiftKeys = []; - this.controlKeys = []; - this.controlShiftKeys = []; - - // Installs the keystroke listener in the target - mxEvent.addListener(this.target, "keydown", - mxUtils.bind(this, function(evt) - { - this.keyDown(evt); - }) - ); - - // Automatically deallocates memory in IE - if (mxClient.IS_IE) - { - mxEvent.addListener(window, 'unload', - mxUtils.bind(this, function() - { - this.destroy(); - }) - ); - } - } -}; - -/** - * Variable: graph - * - * Reference to the associated with this handler. - */ -mxKeyHandler.prototype.graph = null; - -/** - * Variable: target - * - * Reference to the target DOM, that is, the DOM node where the key event - * listeners are installed. - */ -mxKeyHandler.prototype.target = null; - -/** - * Variable: normalKeys - * - * Maps from keycodes to functions for non-pressed control keys. - */ -mxKeyHandler.prototype.normalKeys = null; - -/** - * Variable: shiftKeys - * - * Maps from keycodes to functions for pressed shift keys. - */ -mxKeyHandler.prototype.shiftKeys = null; - -/** - * Variable: controlKeys - * - * Maps from keycodes to functions for pressed control keys. - */ -mxKeyHandler.prototype.controlKeys = null; - -/** - * Variable: controlShiftKeys - * - * Maps from keycodes to functions for pressed control and shift keys. - */ -mxKeyHandler.prototype.controlShiftKeys = null; - -/** - * Variable: enabled - * - * Specifies if events are handled. Default is true. - */ -mxKeyHandler.prototype.enabled = true; - -/** - * Function: isEnabled - * - * Returns true if events are handled. This implementation returns - * . - */ -mxKeyHandler.prototype.isEnabled = function() -{ - return this.enabled; -}; - -/** - * Function: setEnabled - * - * Enables or disables event handling by updating . - * - * Parameters: - * - * enabled - Boolean that specifies the new enabled state. - */ -mxKeyHandler.prototype.setEnabled = function(enabled) -{ - this.enabled = enabled; -}; - -/** - * Function: bindKey - * - * Binds the specified keycode to the given function. This binding is used - * if the control key is not pressed. - * - * Parameters: - * - * code - Integer that specifies the keycode. - * funct - JavaScript function that takes the key event as an argument. - */ -mxKeyHandler.prototype.bindKey = function(code, funct) -{ - this.normalKeys[code] = funct; -}; - -/** - * Function: bindShiftKey - * - * Binds the specified keycode to the given function. This binding is used - * if the shift key is pressed. - * - * Parameters: - * - * code - Integer that specifies the keycode. - * funct - JavaScript function that takes the key event as an argument. - */ -mxKeyHandler.prototype.bindShiftKey = function(code, funct) -{ - this.shiftKeys[code] = funct; -}; - -/** - * Function: bindControlKey - * - * Binds the specified keycode to the given function. This binding is used - * if the control key is pressed. - * - * Parameters: - * - * code - Integer that specifies the keycode. - * funct - JavaScript function that takes the key event as an argument. - */ -mxKeyHandler.prototype.bindControlKey = function(code, funct) -{ - this.controlKeys[code] = funct; -}; - -/** - * Function: bindControlShiftKey - * - * Binds the specified keycode to the given function. This binding is used - * if the control and shift key are pressed. - * - * Parameters: - * - * code - Integer that specifies the keycode. - * funct - JavaScript function that takes the key event as an argument. - */ -mxKeyHandler.prototype.bindControlShiftKey = function(code, funct) -{ - this.controlShiftKeys[code] = funct; -}; - -/** - * Function: isControlDown - * - * Returns true if the control key is pressed. This uses . - * - * Parameters: - * - * evt - Key event whose control key pressed state should be returned. - */ -mxKeyHandler.prototype.isControlDown = function(evt) -{ - return mxEvent.isControlDown(evt); -}; - -/** - * Function: getFunction - * - * Returns the function associated with the given key event or null if no - * function is associated with the given event. - * - * Parameters: - * - * evt - Key event whose associated function should be returned. - */ -mxKeyHandler.prototype.getFunction = function(evt) -{ - if (evt != null) - { - if (this.isControlDown(evt)) - { - if (mxEvent.isShiftDown(evt)) - { - return this.controlShiftKeys[evt.keyCode]; - } - else - { - return this.controlKeys[evt.keyCode]; - } - } - else - { - if (mxEvent.isShiftDown(evt)) - { - return this.shiftKeys[evt.keyCode]; - } - else - { - return this.normalKeys[evt.keyCode]; - } - } - } - - return null; -}; - -/** - * Function: isGraphEvent - * - * Returns true if the event should be processed by this handler, that is, - * if the event source is either the target, one of its direct children, a - * descendant of the , or the of the - * . - * - * Parameters: - * - * evt - Key event that represents the keystroke. - */ -mxKeyHandler.prototype.isGraphEvent = function(evt) -{ - var source = mxEvent.getSource(evt); - - // Accepts events from the target object or - // in-place editing inside graph - if ((source == this.target || source.parentNode == this.target) || - (this.graph.cellEditor != null && source == this.graph.cellEditor.textarea)) - { - return true; - } - - // Accepts events from inside the container - var elt = source; - - while (elt != null) - { - if (elt == this.graph.container) - { - return true; - } - - elt = elt.parentNode; - } - - return false; -}; - -/** - * Function: keyDown - * - * Handles the event by invoking the function bound to the respective - * keystroke if , and all - * return true for the given event and returns false. - * If the graph is editing only the and cases are handled - * by calling the respective hooks. - * - * Parameters: - * - * evt - Key event that represents the keystroke. - */ -mxKeyHandler.prototype.keyDown = function(evt) -{ - if (this.graph.isEnabled() && !mxEvent.isConsumed(evt) && - this.isGraphEvent(evt) && this.isEnabled()) - { - // Cancels the editing if escape is pressed - if (evt.keyCode == 27 /* Escape */) - { - this.escape(evt); - } - - // Invokes the function for the keystroke - else if (!this.graph.isEditing()) - { - var boundFunction = this.getFunction(evt); - - if (boundFunction != null) - { - boundFunction(evt); - mxEvent.consume(evt); - } - } - } -}; - -/** - * Function: escape - * - * Hook to process ESCAPE keystrokes. This implementation invokes - * to cancel the current editing, connecting - * and/or other ongoing modifications. - * - * Parameters: - * - * evt - Key event that represents the keystroke. Possible keycode in this - * case is 27 (ESCAPE). - */ -mxKeyHandler.prototype.escape = function(evt) -{ - if (this.graph.isEscapeEnabled()) - { - this.graph.escape(evt); - } -}; - -/** - * Function: destroy - * - * Destroys the handler and all its references into the DOM. This does - * normally not need to be called, it is called automatically when the - * window unloads (in IE). - */ -mxKeyHandler.prototype.destroy = function() -{ - this.target = null; -}; diff --git a/src/js/handler/mxPanningHandler.js b/src/js/handler/mxPanningHandler.js deleted file mode 100644 index b388144..0000000 --- a/src/js/handler/mxPanningHandler.js +++ /dev/null @@ -1,390 +0,0 @@ -/** - * $Id: mxPanningHandler.js,v 1.79 2012-07-17 14:37:41 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxPanningHandler - * - * Event handler that pans and creates popupmenus. To use the left - * mousebutton for panning without interfering with cell moving and - * resizing, use and . For grid size - * steps while panning, use . This handler is built-into - * and enabled using . - * - * Constructor: mxPanningHandler - * - * Constructs an event handler that creates a - * and pans the graph. - * - * Event: mxEvent.PAN_START - * - * Fires when the panning handler changes its state to true. The - * event property contains the corresponding . - * - * Event: mxEvent.PAN - * - * Fires while handle is processing events. The event property contains - * the corresponding . - * - * Event: mxEvent.PAN_END - * - * Fires when the panning handler changes its state to false. The - * event property contains the corresponding . - */ -function mxPanningHandler(graph, factoryMethod) -{ - if (graph != null) - { - this.graph = graph; - this.factoryMethod = factoryMethod; - this.graph.addMouseListener(this); - this.init(); - } -}; - -/** - * Extends mxPopupMenu. - */ -mxPanningHandler.prototype = new mxPopupMenu(); -mxPanningHandler.prototype.constructor = mxPanningHandler; - -/** - * Variable: graph - * - * Reference to the enclosing . - */ -mxPanningHandler.prototype.graph = null; - -/** - * Variable: usePopupTrigger - * - * Specifies if the should also be used for panning. To - * avoid conflicts, the panning is only activated if the mouse was moved - * more than , otherwise, a single click is assumed - * and the popupmenu is displayed. Default is true. - */ -mxPanningHandler.prototype.usePopupTrigger = true; - -/** - * Variable: useLeftButtonForPanning - * - * Specifies if panning should be active for the left mouse button. - * Setting this to true may conflict with . Default is false. - */ -mxPanningHandler.prototype.useLeftButtonForPanning = false; - -/** - * Variable: selectOnPopup - * - * Specifies if cells should be selected if a popupmenu is displayed for - * them. Default is true. - */ -mxPanningHandler.prototype.selectOnPopup = true; - -/** - * Variable: clearSelectionOnBackground - * - * Specifies if cells should be deselected if a popupmenu is displayed for - * the diagram background. Default is true. - */ -mxPanningHandler.prototype.clearSelectionOnBackground = true; - -/** - * Variable: ignoreCell - * - * Specifies if panning should be active even if there is a cell under the - * mousepointer. Default is false. - */ -mxPanningHandler.prototype.ignoreCell = false; - -/** - * Variable: previewEnabled - * - * Specifies if the panning should be previewed. Default is true. - */ -mxPanningHandler.prototype.previewEnabled = true; - -/** - * Variable: useGrid - * - * Specifies if the panning steps should be aligned to the grid size. - * Default is false. - */ -mxPanningHandler.prototype.useGrid = false; - -/** - * Variable: panningEnabled - * - * Specifies if panning should be enabled. Default is true. - */ -mxPanningHandler.prototype.panningEnabled = true; - -/** - * Function: isPanningEnabled - * - * Returns . - */ -mxPanningHandler.prototype.isPanningEnabled = function() -{ - return this.panningEnabled; -}; - -/** - * Function: setPanningEnabled - * - * Sets . - */ -mxPanningHandler.prototype.setPanningEnabled = function(value) -{ - this.panningEnabled = value; -}; - -/** - * Function: init - * - * Initializes the shapes required for this vertex handler. - */ -mxPanningHandler.prototype.init = function() -{ - // Supercall - mxPopupMenu.prototype.init.apply(this); - - // Hides the tooltip if the mouse is over - // the context menu - mxEvent.addListener(this.div, (mxClient.IS_TOUCH) ? 'touchmove' : 'mousemove', - mxUtils.bind(this, function(evt) - { - this.graph.tooltipHandler.hide(); - }) - ); -}; - -/** - * Function: isPanningTrigger - * - * Returns true if the given event is a panning trigger for the optional - * given cell. This returns true if control-shift is pressed or if - * is true and the event is a popup trigger. - */ -mxPanningHandler.prototype.isPanningTrigger = function(me) -{ - var evt = me.getEvent(); - - return (this.useLeftButtonForPanning && (this.ignoreCell || me.getState() == null) && - mxEvent.isLeftMouseButton(evt)) || (mxEvent.isControlDown(evt) && - mxEvent.isShiftDown(evt)) || (this.usePopupTrigger && - mxEvent.isPopupTrigger(evt)); -}; - -/** - * Function: mouseDown - * - * Handles the event by initiating the panning. By consuming the event all - * subsequent events of the gesture are redirected to this handler. - */ -mxPanningHandler.prototype.mouseDown = function(sender, me) -{ - if (!me.isConsumed() && this.isEnabled()) - { - // Hides the popupmenu if is is being displayed - this.hideMenu(); - - this.dx0 = -this.graph.container.scrollLeft; - this.dy0 = -this.graph.container.scrollTop; - - // Checks the event triggers to panning and popupmenu - this.popupTrigger = this.isPopupTrigger(me); - this.panningTrigger = this.isPanningEnabled() && - this.isPanningTrigger(me); - - // Stores the location of the trigger event - this.startX = me.getX(); - this.startY = me.getY(); - - // Displays popup menu on Mac after the mouse was released - if (this.panningTrigger) - { - this.consumePanningTrigger(me); - } - } -}; - -/** - * Function: consumePanningTrigger - * - * Consumes the given if it was a panning trigger in - * . The default is to invoke . Note that this - * will block any further event processing. If you haven't disabled built-in - * context menus and require immediate selection of the cell on mouseDown in - * Safari and/or on the Mac, then use the following code: - * - * (code) - * mxPanningHandler.prototype.consumePanningTrigger = function(me) - * { - * if (me.evt.preventDefault) - * { - * me.evt.preventDefault(); - * } - * - * // Stops event processing in IE - * me.evt.returnValue = false; - * - * // Sets local consumed state - * if (!mxClient.IS_SF && !mxClient.IS_MAC) - * { - * me.consumed = true; - * } - * }; - * (end) - */ -mxPanningHandler.prototype.consumePanningTrigger = function(me) -{ - me.consume(); -}; - -/** - * Function: mouseMove - * - * Handles the event by updating the panning on the graph. - */ -mxPanningHandler.prototype.mouseMove = function(sender, me) -{ - var dx = me.getX() - this.startX; - var dy = me.getY() - this.startY; - - if (this.active) - { - if (this.previewEnabled) - { - // Applies the grid to the panning steps - if (this.useGrid) - { - dx = this.graph.snap(dx); - dy = this.graph.snap(dy); - } - - this.graph.panGraph(dx + this.dx0, dy + this.dy0); - } - - this.fireEvent(new mxEventObject(mxEvent.PAN, 'event', me)); - me.consume(); - } - else if (this.panningTrigger) - { - var tmp = this.active; - - // Panning is activated only if the mouse is moved - // beyond the graph tolerance - this.active = Math.abs(dx) > this.graph.tolerance || - Math.abs(dy) > this.graph.tolerance; - - if (!tmp && this.active) - { - this.fireEvent(new mxEventObject(mxEvent.PAN_START, 'event', me)); - } - } -}; - -/** - * Function: mouseUp - * - * Handles the event by setting the translation on the view or showing the - * popupmenu. - */ -mxPanningHandler.prototype.mouseUp = function(sender, me) -{ - // Shows popup menu if mouse was not moved - var dx = Math.abs(me.getX() - this.startX); - var dy = Math.abs(me.getY() - this.startY); - - if (this.active) - { - if (!this.graph.useScrollbarsForPanning || !mxUtils.hasScrollbars(this.graph.container)) - { - dx = me.getX() - this.startX; - dy = me.getY() - this.startY; - - // Applies the grid to the panning steps - if (this.useGrid) - { - dx = this.graph.snap(dx); - dy = this.graph.snap(dy); - } - - var scale = this.graph.getView().scale; - var t = this.graph.getView().translate; - - this.graph.panGraph(0, 0); - this.panGraph(t.x + dx / scale, t.y + dy / scale); - } - - this.active = false; - this.fireEvent(new mxEventObject(mxEvent.PAN_END, 'event', me)); - me.consume(); - } - else if (this.popupTrigger) - { - if (dx < this.graph.tolerance && dy < this.graph.tolerance) - { - var cell = this.getCellForPopupEvent(me); - - // Selects the cell for which the context menu is being displayed - if (this.graph.isEnabled() && this.selectOnPopup && - cell != null && !this.graph.isCellSelected(cell)) - { - this.graph.setSelectionCell(cell); - } - else if (this.clearSelectionOnBackground && cell == null) - { - this.graph.clearSelection(); - } - - // Hides the tooltip if there is one - this.graph.tooltipHandler.hide(); - var origin = mxUtils.getScrollOrigin(); - var point = new mxPoint(me.getX() + origin.x, - me.getY() + origin.y); - - // Menu is shifted by 1 pixel so that the mouse up event - // is routed via the underlying shape instead of the DIV - this.popup(point.x + 1, point.y + 1, cell, me.getEvent()); - me.consume(); - } - } - - this.panningTrigger = false; - this.popupTrigger = false; -}; - -/** - * Function: getCellForPopupEvent - * - * Hook to return the cell for the mouse up popup trigger handling. - */ -mxPanningHandler.prototype.getCellForPopupEvent = function(me) -{ - return me.getCell(); -}; - -/** - * Function: panGraph - * - * Pans by the given amount. - */ -mxPanningHandler.prototype.panGraph = function(dx, dy) -{ - this.graph.getView().setTranslate(dx, dy); -}; - -/** - * Function: destroy - * - * Destroys the handler and all its resources and DOM nodes. - */ -mxPanningHandler.prototype.destroy = function() -{ - this.graph.removeMouseListener(this); - - // Supercall - mxPopupMenu.prototype.destroy.apply(this); -}; diff --git a/src/js/handler/mxRubberband.js b/src/js/handler/mxRubberband.js deleted file mode 100644 index f9e7187..0000000 --- a/src/js/handler/mxRubberband.js +++ /dev/null @@ -1,348 +0,0 @@ -/** - * $Id: mxRubberband.js,v 1.48 2012-04-13 12:53:30 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxRubberband - * - * Event handler that selects rectangular regions. This is not built-into - * . To enable rubberband selection in a graph, use the following code. - * - * Example: - * - * (code) - * var rubberband = new mxRubberband(graph); - * (end) - * - * Constructor: mxRubberband - * - * Constructs an event handler that selects rectangular regions in the graph - * using rubberband selection. - */ -function mxRubberband(graph) -{ - if (graph != null) - { - this.graph = graph; - this.graph.addMouseListener(this); - - // Repaints the marquee after autoscroll - this.panHandler = mxUtils.bind(this, function() - { - this.repaint(); - }); - - this.graph.addListener(mxEvent.PAN, this.panHandler); - - // Automatic deallocation of memory - if (mxClient.IS_IE) - { - mxEvent.addListener(window, 'unload', - mxUtils.bind(this, function() - { - this.destroy(); - }) - ); - } - } -}; - -/** - * Variable: defaultOpacity - * - * Specifies the default opacity to be used for the rubberband div. Default - * is 20. - */ -mxRubberband.prototype.defaultOpacity = 20; - -/** - * Variable: enabled - * - * Specifies if events are handled. Default is true. - */ -mxRubberband.prototype.enabled = true; - -/** - * Variable: div - * - * Holds the DIV element which is currently visible. - */ -mxRubberband.prototype.div = null; - -/** - * Variable: sharedDiv - * - * Holds the DIV element which is used to display the rubberband. - */ -mxRubberband.prototype.sharedDiv = null; - -/** - * Variable: currentX - * - * Holds the value of the x argument in the last call to . - */ -mxRubberband.prototype.currentX = 0; - -/** - * Variable: currentY - * - * Holds the value of the y argument in the last call to . - */ -mxRubberband.prototype.currentY = 0; - -/** - * Function: isEnabled - * - * Returns true if events are handled. This implementation returns - * . - */ -mxRubberband.prototype.isEnabled = function() -{ - return this.enabled; -}; - -/** - * Function: setEnabled - * - * Enables or disables event handling. This implementation updates - * . - */ -mxRubberband.prototype.setEnabled = function(enabled) -{ - this.enabled = enabled; -}; - -/** - * Function: mouseDown - * - * Handles the event by initiating a rubberband selection. By consuming the - * event all subsequent events of the gesture are redirected to this - * handler. - */ -mxRubberband.prototype.mouseDown = function(sender, me) -{ - if (!me.isConsumed() && this.isEnabled() && this.graph.isEnabled() && - (this.graph.isForceMarqueeEvent(me.getEvent()) || me.getState() == null)) - { - var offset = mxUtils.getOffset(this.graph.container); - var origin = mxUtils.getScrollOrigin(this.graph.container); - origin.x -= offset.x; - origin.y -= offset.y; - this.start(me.getX() + origin.x, me.getY() + origin.y); - - // Workaround for rubberband stopping if the mouse leaves the - // graph container in Firefox. - if (mxClient.IS_NS && !mxClient.IS_SF && !mxClient.IS_GC) - { - var container = this.graph.container; - - function createMouseEvent(evt) - { - var me = new mxMouseEvent(evt); - var pt = mxUtils.convertPoint(container, me.getX(), me.getY()); - - me.graphX = pt.x; - me.graphY = pt.y; - - return me; - }; - - this.dragHandler = mxUtils.bind(this, function(evt) - { - this.mouseMove(this.graph, createMouseEvent(evt)); - }); - - this.dropHandler = mxUtils.bind(this, function(evt) - { - this.mouseUp(this.graph, createMouseEvent(evt)); - }); - - mxEvent.addListener(document, 'mousemove', this.dragHandler); - mxEvent.addListener(document, 'mouseup', this.dropHandler); - } - - // Does not prevent the default for this event so that the - // event processing chain is still executed even if we start - // rubberbanding. This is required eg. in ExtJs to hide the - // current context menu. In mouseMove we'll make sure we're - // not selecting anything while we're rubberbanding. - me.consume(false); - } -}; - -/** - * Function: start - * - * Sets the start point for the rubberband selection. - */ -mxRubberband.prototype.start = function(x, y) -{ - this.first = new mxPoint(x, y); -}; - -/** - * Function: mouseMove - * - * Handles the event by updating therubberband selection. - */ -mxRubberband.prototype.mouseMove = function(sender, me) -{ - if (!me.isConsumed() && this.first != null) - { - var origin = mxUtils.getScrollOrigin(this.graph.container); - var offset = mxUtils.getOffset(this.graph.container); - origin.x -= offset.x; - origin.y -= offset.y; - var x = me.getX() + origin.x; - var y = me.getY() + origin.y; - var dx = this.first.x - x; - var dy = this.first.y - y; - var tol = this.graph.tolerance; - - if (this.div != null || Math.abs(dx) > tol || Math.abs(dy) > tol) - { - if (this.div == null) - { - this.div = this.createShape(); - } - - // Clears selection while rubberbanding. This is required because - // the event is not consumed in mouseDown. - mxUtils.clearSelection(); - - this.update(x, y); - me.consume(); - } - } -}; - -/** - * Function: createShape - * - * Creates the rubberband selection shape. - */ -mxRubberband.prototype.createShape = function() -{ - if (this.sharedDiv == null) - { - this.sharedDiv = document.createElement('div'); - this.sharedDiv.className = 'mxRubberband'; - mxUtils.setOpacity(this.sharedDiv, this.defaultOpacity); - } - - this.graph.container.appendChild(this.sharedDiv); - - return this.sharedDiv; -}; - -/** - * Function: mouseUp - * - * Handles the event by selecting the region of the rubberband using - * . - */ -mxRubberband.prototype.mouseUp = function(sender, me) -{ - var execute = this.div != null; - this.reset(); - - if (execute) - { - var rect = new mxRectangle(this.x, this.y, this.width, this.height); - this.graph.selectRegion(rect, me.getEvent()); - me.consume(); - } -}; - -/** - * Function: reset - * - * Resets the state of the rubberband selection. - */ -mxRubberband.prototype.reset = function() -{ - if (this.div != null) - { - this.div.parentNode.removeChild(this.div); - } - - if (this.dragHandler != null) - { - mxEvent.removeListener(document, 'mousemove', this.dragHandler); - this.dragHandler = null; - } - - if (this.dropHandler != null) - { - mxEvent.removeListener(document, 'mouseup', this.dropHandler); - this.dropHandler = null; - } - - this.currentX = 0; - this.currentY = 0; - this.first = null; - this.div = null; -}; - -/** - * Function: update - * - * Sets and and calls . - */ -mxRubberband.prototype.update = function(x, y) -{ - this.currentX = x; - this.currentY = y; - - this.repaint(); -}; - -/** - * Function: repaint - * - * Computes the bounding box and updates the style of the
. - */ -mxRubberband.prototype.repaint = function() -{ - if (this.div != null) - { - var x = this.currentX - this.graph.panDx; - var y = this.currentY - this.graph.panDy; - - this.x = Math.min(this.first.x, x); - this.y = Math.min(this.first.y, y); - this.width = Math.max(this.first.x, x) - this.x; - this.height = Math.max(this.first.y, y) - this.y; - - var dx = (mxClient.IS_VML) ? this.graph.panDx : 0; - var dy = (mxClient.IS_VML) ? this.graph.panDy : 0; - - this.div.style.left = (this.x + dx) + 'px'; - this.div.style.top = (this.y + dy) + 'px'; - this.div.style.width = Math.max(1, this.width) + 'px'; - this.div.style.height = Math.max(1, this.height) + 'px'; - } -}; - -/** - * Function: destroy - * - * Destroys the handler and all its resources and DOM nodes. This does - * normally not need to be called, it is called automatically when the - * window unloads. - */ -mxRubberband.prototype.destroy = function() -{ - if (!this.destroyed) - { - this.destroyed = true; - this.graph.removeMouseListener(this); - this.graph.removeListener(this.panHandler); - this.reset(); - - if (this.sharedDiv != null) - { - this.sharedDiv = null; - } - } -}; diff --git a/src/js/handler/mxSelectionCellsHandler.js b/src/js/handler/mxSelectionCellsHandler.js deleted file mode 100644 index 800d718..0000000 --- a/src/js/handler/mxSelectionCellsHandler.js +++ /dev/null @@ -1,260 +0,0 @@ -/** - * $Id: mxSelectionCellsHandler.js,v 1.5 2012-08-10 11:35:06 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxSelectionCellsHandler - * - * An event handler that manages cell handlers and invokes their mouse event - * processing functions. - * - * Group: Events - * - * Event: mxEvent.ADD - * - * Fires if a cell has been added to the selection. The state - * property contains the that has been added. - * - * Event: mxEvent.REMOVE - * - * Fires if a cell has been remove from the selection. The state - * property contains the that has been removed. - * - * Parameters: - * - * graph - Reference to the enclosing . - */ -function mxSelectionCellsHandler(graph) -{ - this.graph = graph; - this.handlers = new mxDictionary(); - this.graph.addMouseListener(this); - - this.refreshHandler = mxUtils.bind(this, function(sender, evt) - { - if (this.isEnabled()) - { - this.refresh(); - } - }); - - this.graph.getSelectionModel().addListener(mxEvent.CHANGE, this.refreshHandler); - this.graph.getModel().addListener(mxEvent.CHANGE, this.refreshHandler); - this.graph.getView().addListener(mxEvent.SCALE, this.refreshHandler); - this.graph.getView().addListener(mxEvent.TRANSLATE, this.refreshHandler); - this.graph.getView().addListener(mxEvent.SCALE_AND_TRANSLATE, this.refreshHandler); - this.graph.getView().addListener(mxEvent.DOWN, this.refreshHandler); - this.graph.getView().addListener(mxEvent.UP, this.refreshHandler); -}; - -/** - * Extends mxEventSource. - */ -mxSelectionCellsHandler.prototype = new mxEventSource(); -mxSelectionCellsHandler.prototype.constructor = mxSelectionCellsHandler; - -/** - * Variable: graph - * - * Reference to the enclosing . - */ -mxSelectionCellsHandler.prototype.graph = null; - -/** - * Variable: enabled - * - * Specifies if events are handled. Default is true. - */ -mxSelectionCellsHandler.prototype.enabled = true; - -/** - * Variable: refreshHandler - * - * Keeps a reference to an event listener for later removal. - */ -mxSelectionCellsHandler.prototype.refreshHandler = null; - -/** - * Variable: maxHandlers - * - * Defines the maximum number of handlers to paint individually. Default is 100. - */ -mxSelectionCellsHandler.prototype.maxHandlers = 100; - -/** - * Variable: handlers - * - * that maps from cells to handlers. - */ -mxSelectionCellsHandler.prototype.handlers = null; - -/** - * Function: isEnabled - * - * Returns . - */ -mxSelectionCellsHandler.prototype.isEnabled = function() -{ - return this.enabled; -}; - -/** - * Function: setEnabled - * - * Sets . - */ -mxSelectionCellsHandler.prototype.setEnabled = function(value) -{ - this.enabled = value; -}; - -/** - * Function: getHandler - * - * Returns the handler for the given cell. - */ -mxSelectionCellsHandler.prototype.getHandler = function(cell) -{ - return this.handlers.get(cell); -}; - -/** - * Function: reset - * - * Resets all handlers. - */ -mxSelectionCellsHandler.prototype.reset = function() -{ - this.handlers.visit(function(key, handler) - { - handler.reset.apply(handler); - }); -}; - -/** - * Function: refresh - * - * Reloads or updates all handlers. - */ -mxSelectionCellsHandler.prototype.refresh = function() -{ - // Removes all existing handlers - var oldHandlers = this.handlers; - this.handlers = new mxDictionary(); - - // Creates handles for all selection cells - var tmp = this.graph.getSelectionCells(); - - for (var i = 0; i < tmp.length; i++) - { - var state = this.graph.view.getState(tmp[i]); - - if (state != null) - { - var handler = oldHandlers.remove(tmp[i]); - - if (handler != null) - { - if (handler.state != state) - { - handler.destroy(); - handler = null; - } - else - { - handler.redraw(); - } - } - - if (handler == null) - { - handler = this.graph.createHandler(state); - this.fireEvent(new mxEventObject(mxEvent.ADD, 'state', state)); - } - - if (handler != null) - { - this.handlers.put(tmp[i], handler); - } - } - } - - // Destroys all unused handlers - oldHandlers.visit(mxUtils.bind(this, function(key, handler) - { - this.fireEvent(new mxEventObject(mxEvent.REMOVE, 'state', handler.state)); - handler.destroy(); - })); -}; - -/** - * Function: mouseDown - * - * Redirects the given event to the handlers. - */ -mxSelectionCellsHandler.prototype.mouseDown = function(sender, me) -{ - if (this.graph.isEnabled() && this.isEnabled()) - { - var args = [sender, me]; - - this.handlers.visit(function(key, handler) - { - handler.mouseDown.apply(handler, args); - }); - } -}; - -/** - * Function: mouseMove - * - * Redirects the given event to the handlers. - */ -mxSelectionCellsHandler.prototype.mouseMove = function(sender, me) -{ - if (this.graph.isEnabled() && this.isEnabled()) - { - var args = [sender, me]; - - this.handlers.visit(function(key, handler) - { - handler.mouseMove.apply(handler, args); - }); - } -}; - -/** - * Function: mouseUp - * - * Redirects the given event to the handlers. - */ -mxSelectionCellsHandler.prototype.mouseUp = function(sender, me) -{ - if (this.graph.isEnabled() && this.isEnabled()) - { - var args = [sender, me]; - - this.handlers.visit(function(key, handler) - { - handler.mouseUp.apply(handler, args); - }); - } -}; - -/** - * Function: destroy - * - * Destroys the handler and all its resources and DOM nodes. - */ -mxSelectionCellsHandler.prototype.destroy = function() -{ - this.graph.removeMouseListener(this); - - if (this.refreshHandler != null) - { - this.graph.getSelectionModel().removeListener(this.refreshHandler); - this.graph.getModel().removeListener(this.refreshHandler); - this.graph.getView().removeListener(this.refreshHandler); - this.refreshHandler = null; - } -}; diff --git a/src/js/handler/mxTooltipHandler.js b/src/js/handler/mxTooltipHandler.js deleted file mode 100644 index 4e34a13..0000000 --- a/src/js/handler/mxTooltipHandler.js +++ /dev/null @@ -1,317 +0,0 @@ -/** - * $Id: mxTooltipHandler.js,v 1.51 2011-03-31 10:11:17 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxTooltipHandler - * - * Graph event handler that displays tooltips. is used to - * get the tooltip for a cell or handle. This handler is built-into - * and enabled using . - * - * Example: - * - * (code> - * new mxTooltipHandler(graph); - * (end) - * - * Constructor: mxTooltipHandler - * - * Constructs an event handler that displays tooltips with the specified - * delay (in milliseconds). If no delay is specified then a default delay - * of 500 ms (0.5 sec) is used. - * - * Parameters: - * - * graph - Reference to the enclosing . - * delay - Optional delay in milliseconds. - */ -function mxTooltipHandler(graph, delay) -{ - if (graph != null) - { - this.graph = graph; - this.delay = delay || 500; - this.graph.addMouseListener(this); - } -}; - -/** - * Variable: zIndex - * - * Specifies the zIndex for the tooltip and its shadow. Default is 10005. - */ -mxTooltipHandler.prototype.zIndex = 10005; - -/** - * Variable: graph - * - * Reference to the enclosing . - */ -mxTooltipHandler.prototype.graph = null; - -/** - * Variable: delay - * - * Delay to show the tooltip in milliseconds. Default is 500. - */ -mxTooltipHandler.prototype.delay = null; - -/** - * Variable: hideOnHover - * - * Specifies if the tooltip should be hidden if the mouse is moved over the - * current cell. Default is false. - */ -mxTooltipHandler.prototype.hideOnHover = false; - -/** - * Variable: enabled - * - * Specifies if events are handled. Default is true. - */ -mxTooltipHandler.prototype.enabled = true; - -/** - * Function: isEnabled - * - * Returns true if events are handled. This implementation - * returns . - */ -mxTooltipHandler.prototype.isEnabled = function() -{ - return this.enabled; -}; - -/** - * Function: setEnabled - * - * Enables or disables event handling. This implementation - * updates . - */ -mxTooltipHandler.prototype.setEnabled = function(enabled) -{ - this.enabled = enabled; -}; - -/** - * Function: isHideOnHover - * - * Returns . - */ -mxTooltipHandler.prototype.isHideOnHover = function() -{ - return this.hideOnHover; -}; - -/** - * Function: setHideOnHover - * - * Sets . - */ -mxTooltipHandler.prototype.setHideOnHover = function(value) -{ - this.hideOnHover = value; -}; - -/** - * Function: init - * - * Initializes the DOM nodes required for this tooltip handler. - */ -mxTooltipHandler.prototype.init = function() -{ - if (document.body != null) - { - this.div = document.createElement('div'); - this.div.className = 'mxTooltip'; - this.div.style.visibility = 'hidden'; - this.div.style.zIndex = this.zIndex; - - document.body.appendChild(this.div); - - mxEvent.addListener(this.div, 'mousedown', - mxUtils.bind(this, function(evt) - { - this.hideTooltip(); - }) - ); - } -}; - -/** - * Function: mouseDown - * - * Handles the event by initiating a rubberband selection. By consuming the - * event all subsequent events of the gesture are redirected to this - * handler. - */ -mxTooltipHandler.prototype.mouseDown = function(sender, me) -{ - this.reset(me, false); - this.hideTooltip(); -}; - -/** - * Function: mouseMove - * - * Handles the event by updating the rubberband selection. - */ -mxTooltipHandler.prototype.mouseMove = function(sender, me) -{ - if (me.getX() != this.lastX || me.getY() != this.lastY) - { - this.reset(me, true); - - if (this.isHideOnHover() || me.getState() != this.state || (me.getSource() != this.node && - (!this.stateSource || (me.getState() != null && this.stateSource == - (me.isSource(me.getState().shape) || !me.isSource(me.getState().text)))))) - { - this.hideTooltip(); - } - } - - this.lastX = me.getX(); - this.lastY = me.getY(); -}; - -/** - * Function: mouseUp - * - * Handles the event by resetting the tooltip timer or hiding the existing - * tooltip. - */ -mxTooltipHandler.prototype.mouseUp = function(sender, me) -{ - this.reset(me, true); - this.hideTooltip(); -}; - - -/** - * Function: resetTimer - * - * Resets the timer. - */ -mxTooltipHandler.prototype.resetTimer = function() -{ - if (this.thread != null) - { - window.clearTimeout(this.thread); - this.thread = null; - } -}; - -/** - * Function: reset - * - * Resets and/or restarts the timer to trigger the display of the tooltip. - */ -mxTooltipHandler.prototype.reset = function(me, restart) -{ - this.resetTimer(); - - if (restart && this.isEnabled() && me.getState() != null && (this.div == null || - this.div.style.visibility == 'hidden')) - { - var state = me.getState(); - var node = me.getSource(); - var x = me.getX(); - var y = me.getY(); - var stateSource = me.isSource(state.shape) || me.isSource(state.text); - - this.thread = window.setTimeout(mxUtils.bind(this, function() - { - if (!this.graph.isEditing() && !this.graph.panningHandler.isMenuShowing()) - { - // Uses information from inside event cause using the event at - // this (delayed) point in time is not possible in IE as it no - // longer contains the required information (member not found) - var tip = this.graph.getTooltip(state, node, x, y); - this.show(tip, x, y); - this.state = state; - this.node = node; - this.stateSource = stateSource; - } - }), this.delay); - } -}; - -/** - * Function: hide - * - * Hides the tooltip and resets the timer. - */ -mxTooltipHandler.prototype.hide = function() -{ - this.resetTimer(); - this.hideTooltip(); -}; - -/** - * Function: hideTooltip - * - * Hides the tooltip. - */ -mxTooltipHandler.prototype.hideTooltip = function() -{ - if (this.div != null) - { - this.div.style.visibility = 'hidden'; - } -}; - -/** - * Function: show - * - * Shows the tooltip for the specified cell and optional index at the - * specified location (with a vertical offset of 10 pixels). - */ -mxTooltipHandler.prototype.show = function(tip, x, y) -{ - if (tip != null && tip.length > 0) - { - // Initializes the DOM nodes if required - if (this.div == null) - { - this.init(); - } - - var origin = mxUtils.getScrollOrigin(); - - this.div.style.left = (x + origin.x) + 'px'; - this.div.style.top = (y + mxConstants.TOOLTIP_VERTICAL_OFFSET + - origin.y) + 'px'; - - if (!mxUtils.isNode(tip)) - { - this.div.innerHTML = tip.replace(/\n/g, '
'); - } - else - { - this.div.innerHTML = ''; - this.div.appendChild(tip); - } - - this.div.style.visibility = ''; - mxUtils.fit(this.div); - } -}; - -/** - * Function: destroy - * - * Destroys the handler and all its resources and DOM nodes. - */ -mxTooltipHandler.prototype.destroy = function() -{ - this.graph.removeMouseListener(this); - mxEvent.release(this.div); - - if (this.div != null && this.div.parentNode != null) - { - this.div.parentNode.removeChild(this.div); - } - - this.div = null; -}; diff --git a/src/js/handler/mxVertexHandler.js b/src/js/handler/mxVertexHandler.js deleted file mode 100644 index 0b12e27..0000000 --- a/src/js/handler/mxVertexHandler.js +++ /dev/null @@ -1,753 +0,0 @@ -/** - * $Id: mxVertexHandler.js,v 1.107 2012-11-20 09:06:07 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxVertexHandler - * - * Event handler for resizing cells. This handler is automatically created in - * . - * - * Constructor: mxVertexHandler - * - * Constructs an event handler that allows to resize vertices - * and groups. - * - * Parameters: - * - * state - of the cell to be resized. - */ -function mxVertexHandler(state) -{ - if (state != null) - { - this.state = state; - this.init(); - } -}; - -/** - * Variable: graph - * - * Reference to the enclosing . - */ -mxVertexHandler.prototype.graph = null; - -/** - * Variable: state - * - * Reference to the being modified. - */ -mxVertexHandler.prototype.state = null; - -/** - * Variable: singleSizer - * - * Specifies if only one sizer handle at the bottom, right corner should be - * used. Default is false. - */ -mxVertexHandler.prototype.singleSizer = false; - -/** - * Variable: index - * - * Holds the index of the current handle. - */ -mxVertexHandler.prototype.index = null; - -/** - * Variable: allowHandleBoundsCheck - * - * Specifies if the bounds of handles should be used for hit-detection in IE - * Default is true. - */ -mxVertexHandler.prototype.allowHandleBoundsCheck = true; - -/** - * Variable: crisp - * - * Specifies if the selection bounds and handles should be rendered in crisp - * mode. Default is true. - */ -mxVertexHandler.prototype.crisp = true; - -/** - * Variable: handleImage - * - * Optional to be used as handles. Default is null. - */ -mxVertexHandler.prototype.handleImage = null; - -/** - * Variable: tolerance - * - * Optional tolerance for hit-detection in . Default is 0. - */ -mxVertexHandler.prototype.tolerance = 0; - -/** - * Function: init - * - * Initializes the shapes required for this vertex handler. - */ -mxVertexHandler.prototype.init = function() -{ - this.graph = this.state.view.graph; - this.selectionBounds = this.getSelectionBounds(this.state); - this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y, - this.selectionBounds.width, this.selectionBounds.height); - this.selectionBorder = this.createSelectionShape(this.bounds); - this.selectionBorder.dialect = - (this.graph.dialect != mxConstants.DIALECT_SVG) ? - mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG; - this.selectionBorder.init(this.graph.getView().getOverlayPane()); - - // Event-transparency - if (this.selectionBorder.dialect == mxConstants.DIALECT_SVG) - { - this.selectionBorder.node.setAttribute('pointer-events', 'none'); - } - else - { - this.selectionBorder.node.style.background = ''; - } - - if (this.graph.isCellMovable(this.state.cell)) - { - this.selectionBorder.node.style.cursor = mxConstants.CURSOR_MOVABLE_VERTEX; - } - - mxEvent.redirectMouseEvents(this.selectionBorder.node, this.graph, this.state); - - // Adds the sizer handles - if (mxGraphHandler.prototype.maxCells <= 0 || - this.graph.getSelectionCount() < mxGraphHandler.prototype.maxCells) - { - var resizable = this.graph.isCellResizable(this.state.cell); - this.sizers = []; - - if (resizable || (this.graph.isLabelMovable(this.state.cell) && - this.state.width >= 2 && this.state.height >= 2)) - { - var i = 0; - - if (resizable) - { - if (!this.singleSizer) - { - this.sizers.push(this.createSizer('nw-resize', i++)); - this.sizers.push(this.createSizer('n-resize', i++)); - this.sizers.push(this.createSizer('ne-resize', i++)); - this.sizers.push(this.createSizer('w-resize', i++)); - this.sizers.push(this.createSizer('e-resize', i++)); - this.sizers.push(this.createSizer('sw-resize', i++)); - this.sizers.push(this.createSizer('s-resize', i++)); - } - - this.sizers.push(this.createSizer('se-resize', i++)); - } - - var geo = this.graph.model.getGeometry(this.state.cell); - - if (geo != null && !geo.relative && !this.graph.isSwimlane(this.state.cell) && - this.graph.isLabelMovable(this.state.cell)) - { - // Marks this as the label handle for getHandleForEvent - this.labelShape = this.createSizer(mxConstants.CURSOR_LABEL_HANDLE, - mxEvent.LABEL_HANDLE, mxConstants.LABEL_HANDLE_SIZE, - mxConstants.LABEL_HANDLE_FILLCOLOR); - this.sizers.push(this.labelShape); - } - } - else if (this.graph.isCellMovable(this.state.cell) && !this.graph.isCellResizable(this.state.cell) && - this.state.width < 2 && this.state.height < 2) - { - this.labelShape = this.createSizer(mxConstants.CURSOR_MOVABLE_VERTEX, - null, null, mxConstants.LABEL_HANDLE_FILLCOLOR); - this.sizers.push(this.labelShape); - } - } - - this.redraw(); -}; - -/** - * Function: getSelectionBounds - * - * Returns the mxRectangle that defines the bounds of the selection - * border. - */ -mxVertexHandler.prototype.getSelectionBounds = function(state) -{ - return new mxRectangle(state.x, state.y, state.width, state.height); -}; - -/** - * Function: createSelectionShape - * - * Creates the shape used to draw the selection border. - */ -mxVertexHandler.prototype.createSelectionShape = function(bounds) -{ - var shape = new mxRectangleShape(bounds, null, this.getSelectionColor()); - shape.strokewidth = this.getSelectionStrokeWidth(); - shape.isDashed = this.isSelectionDashed(); - shape.crisp = this.crisp; - - return shape; -}; - -/** - * Function: getSelectionColor - * - * Returns . - */ -mxVertexHandler.prototype.getSelectionColor = function() -{ - return mxConstants.VERTEX_SELECTION_COLOR; -}; - -/** - * Function: getSelectionStrokeWidth - * - * Returns . - */ -mxVertexHandler.prototype.getSelectionStrokeWidth = function() -{ - return mxConstants.VERTEX_SELECTION_STROKEWIDTH; -}; - -/** - * Function: isSelectionDashed - * - * Returns . - */ -mxVertexHandler.prototype.isSelectionDashed = function() -{ - return mxConstants.VERTEX_SELECTION_DASHED; -}; - -/** - * Function: createSizer - * - * Creates a sizer handle for the specified cursor and index and returns - * the new that represents the handle. - */ -mxVertexHandler.prototype.createSizer = function(cursor, index, size, fillColor) -{ - size = size || mxConstants.HANDLE_SIZE; - - var bounds = new mxRectangle(0, 0, size, size); - var sizer = this.createSizerShape(bounds, index, fillColor); - - if (this.state.text != null && this.state.text.node.parentNode == this.graph.container) - { - sizer.bounds.height -= 1; - sizer.bounds.width -= 1; - sizer.dialect = mxConstants.DIALECT_STRICTHTML; - sizer.init(this.graph.container); - } - else - { - sizer.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? - mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG; - sizer.init(this.graph.getView().getOverlayPane()); - } - - mxEvent.redirectMouseEvents(sizer.node, this.graph, this.state); - - if (this.graph.isEnabled()) - { - sizer.node.style.cursor = cursor; - } - - if (!this.isSizerVisible(index)) - { - sizer.node.style.visibility = 'hidden'; - } - - return sizer; -}; - -/** - * Function: isSizerVisible - * - * Returns true if the sizer for the given index is visible. - * This returns true for all given indices. - */ -mxVertexHandler.prototype.isSizerVisible = function(index) -{ - return true; -}; - -/** - * Function: createSizerShape - * - * Creates the shape used for the sizer handle for the specified bounds and - * index. - */ -mxVertexHandler.prototype.createSizerShape = function(bounds, index, fillColor) -{ - if (this.handleImage != null) - { - bounds.width = this.handleImage.width; - bounds.height = this.handleImage.height; - - return new mxImageShape(bounds, this.handleImage.src); - } - else - { - var shape = new mxRectangleShape(bounds, - fillColor || mxConstants.HANDLE_FILLCOLOR, - mxConstants.HANDLE_STROKECOLOR); - shape.crisp = this.crisp; - - return shape; - } -}; - -/** - * Function: createBounds - * - * Helper method to create an around the given centerpoint - * with a width and height of 2*s or 6, if no s is given. - */ -mxVertexHandler.prototype.moveSizerTo = function(shape, x, y) -{ - if (shape != null) - { - shape.bounds.x = x - shape.bounds.width / 2; - shape.bounds.y = y - shape.bounds.height / 2; - shape.redraw(); - } -}; - -/** - * Function: getHandleForEvent - * - * Returns the index of the handle for the given event. This returns the index - * of the sizer from where the event originated or . - */ -mxVertexHandler.prototype.getHandleForEvent = function(me) -{ - if (me.isSource(this.labelShape)) - { - return mxEvent.LABEL_HANDLE; - } - - if (this.sizers != null) - { - // Connection highlight may consume events before they reach sizer handle - var tol = this.tolerance; - var hit = (this.allowHandleBoundsCheck && (mxClient.IS_IE || tol > 0)) ? - new mxRectangle(me.getGraphX() - tol, me.getGraphY() - tol, 2 * tol, 2 * tol) : null; - - for (var i = 0; i < this.sizers.length; i++) - { - if (me.isSource(this.sizers[i]) || (hit != null && - this.sizers[i].node.style.visibility != 'hidden' && - mxUtils.intersects(this.sizers[i].bounds, hit))) - { - return i; - } - } - } - - return null; -}; - -/** - * Function: mouseDown - * - * Handles the event if a handle has been clicked. By consuming the - * event all subsequent events of the gesture are redirected to this - * handler. - */ -mxVertexHandler.prototype.mouseDown = function(sender, me) -{ - if (!me.isConsumed() && this.graph.isEnabled() && !this.graph.isForceMarqueeEvent(me.getEvent()) && - (this.tolerance > 0 || me.getState() == this.state)) - { - var handle = this.getHandleForEvent(me); - - if (handle != null) - { - this.start(me.getX(), me.getY(), handle); - me.consume(); - } - } -}; - -/** - * Function: start - * - * Starts the handling of the mouse gesture. - */ -mxVertexHandler.prototype.start = function(x, y, index) -{ - var pt = mxUtils.convertPoint(this.graph.container, x, y); - this.startX = pt.x; - this.startY = pt.y; - this.index = index; - - // Creates a preview that can be on top of any HTML label - this.selectionBorder.node.style.visibility = 'hidden'; - this.preview = this.createSelectionShape(this.bounds); - - if (this.state.text != null && this.state.text.node.parentNode == this.graph.container) - { - this.preview.dialect = mxConstants.DIALECT_STRICTHTML; - this.preview.init(this.graph.container); - } - else - { - this.preview.dialect = (this.graph.dialect != mxConstants.DIALECT_SVG) ? - mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG; - this.preview.init(this.graph.view.getOverlayPane()); - } -}; - -/** - * Function: mouseMove - * - * Handles the event by updating the preview. - */ -mxVertexHandler.prototype.mouseMove = function(sender, me) -{ - if (!me.isConsumed() && this.index != null) - { - var point = new mxPoint(me.getGraphX(), me.getGraphY()); - var gridEnabled = this.graph.isGridEnabledEvent(me.getEvent()); - var scale = this.graph.getView().scale; - - if (this.index == mxEvent.LABEL_HANDLE) - { - if (gridEnabled) - { - point.x = this.graph.snap(point.x / scale) * scale; - point.y = this.graph.snap(point.y / scale) * scale; - } - - this.moveSizerTo(this.sizers[this.sizers.length - 1], point.x, point.y); - me.consume(); - } - else if (this.index != null) - { - var dx = point.x - this.startX; - var dy = point.y - this.startY; - var tr = this.graph.view.translate; - this.bounds = this.union(this.selectionBounds, dx, dy, this.index, gridEnabled, scale, tr); - this.drawPreview(); - me.consume(); - } - } - // Workaround for disabling the connect highlight when over handle - else if (this.getHandleForEvent(me) != null) - { - me.consume(false); - } -}; - -/** - * Function: mouseUp - * - * Handles the event by applying the changes to the geometry. - */ -mxVertexHandler.prototype.mouseUp = function(sender, me) -{ - if (!me.isConsumed() && this.index != null && this.state != null) - { - var point = new mxPoint(me.getGraphX(), me.getGraphY()); - var scale = this.graph.getView().scale; - - var gridEnabled = this.graph.isGridEnabledEvent(me.getEvent()); - var dx = (point.x - this.startX) / scale; - var dy = (point.y - this.startY) / scale; - - this.resizeCell(this.state.cell, dx, dy, this.index, gridEnabled); - this.reset(); - me.consume(); - } -}; - -/** - * Function: reset - * - * Resets the state of this handler. - */ -mxVertexHandler.prototype.reset = function() -{ - this.index = null; - - if (this.preview != null) - { - this.preview.destroy(); - this.preview = null; - } - - // Checks if handler has been destroyed - if (this.selectionBorder != null) - { - this.selectionBounds = this.getSelectionBounds(this.state); - this.selectionBorder.node.style.visibility = 'visible'; - this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y, - this.selectionBounds.width, this.selectionBounds.height); - this.drawPreview(); - } -}; - -/** - * Function: resizeCell - * - * Uses the given vector to change the bounds of the given cell - * in the graph using . - */ -mxVertexHandler.prototype.resizeCell = function(cell, dx, dy, index, gridEnabled) -{ - var geo = this.graph.model.getGeometry(cell); - - if (index == mxEvent.LABEL_HANDLE) - { - var scale = this.graph.view.scale; - dx = (this.labelShape.bounds.getCenterX() - this.startX) / scale; - dy = (this.labelShape.bounds.getCenterY() - this.startY) / scale; - - geo = geo.clone(); - - if (geo.offset == null) - { - geo.offset = new mxPoint(dx, dy); - } - else - { - geo.offset.x += dx; - geo.offset.y += dy; - } - - this.graph.model.setGeometry(cell, geo); - } - else - { - var bounds = this.union(geo, dx, dy, index, gridEnabled, 1, new mxPoint(0, 0)); - this.graph.resizeCell(cell, bounds); - } -}; - -/** - * Function: union - * - * Returns the union of the given bounds and location for the specified - * handle index. - * - * To override this to limit the size of vertex via a minWidth/-Height style, - * the following code can be used. - * - * (code) - * var vertexHandlerUnion = mxVertexHandler.prototype.union; - * mxVertexHandler.prototype.union = function(bounds, dx, dy, index, gridEnabled, scale, tr) - * { - * var result = vertexHandlerUnion.apply(this, arguments); - * - * result.width = Math.max(result.width, mxUtils.getNumber(this.state.style, 'minWidth', 0)); - * result.height = Math.max(result.height, mxUtils.getNumber(this.state.style, 'minHeight', 0)); - * - * return result; - * }; - * (end) - * - * The minWidth/-Height style can then be used as follows: - * - * (code) - * graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30, 'minWidth=100;minHeight=100;'); - * (end) - */ -mxVertexHandler.prototype.union = function(bounds, dx, dy, index, gridEnabled, scale, tr) -{ - if (this.singleSizer) - { - var x = bounds.x + bounds.width + dx; - var y = bounds.y + bounds.height + dy; - - if (gridEnabled) - { - x = this.graph.snap(x / scale) * scale; - y = this.graph.snap(y / scale) * scale; - } - - var rect = new mxRectangle(bounds.x, bounds.y, 0, 0); - rect.add(new mxRectangle(x, y, 0, 0)); - - return rect; - } - else - { - var left = bounds.x - tr.x * scale; - var right = left + bounds.width; - var top = bounds.y - tr.y * scale; - var bottom = top + bounds.height; - - if (index > 4 /* Bottom Row */) - { - bottom = bottom + dy; - - if (gridEnabled) - { - bottom = this.graph.snap(bottom / scale) * scale; - } - } - else if (index < 3 /* Top Row */) - { - top = top + dy; - - if (gridEnabled) - { - top = this.graph.snap(top / scale) * scale; - } - } - - if (index == 0 || index == 3 || index == 5 /* Left */) - { - left += dx; - - if (gridEnabled) - { - left = this.graph.snap(left / scale) * scale; - } - } - else if (index == 2 || index == 4 || index == 7 /* Right */) - { - right += dx; - - if (gridEnabled) - { - right = this.graph.snap(right / scale) * scale; - } - } - - var width = right - left; - var height = bottom - top; - - // Flips over left side - if (width < 0) - { - left += width; - width = Math.abs(width); - } - - // Flips over top side - if (height < 0) - { - top += height; - height = Math.abs(height); - } - - return new mxRectangle(left + tr.x * scale, top + tr.y * scale, width, height); - } -}; - -/** - * Function: redraw - * - * Redraws the handles and the preview. - */ -mxVertexHandler.prototype.redraw = function() -{ - this.selectionBounds = this.getSelectionBounds(this.state); - this.bounds = new mxRectangle(this.selectionBounds.x, this.selectionBounds.y, - this.selectionBounds.width, this.selectionBounds.height); - - if (this.sizers != null) - { - var s = this.state; - var r = s.x + s.width; - var b = s.y + s.height; - - if (this.singleSizer) - { - this.moveSizerTo(this.sizers[0], r, b); - } - else - { - var cx = s.x + s.width / 2; - var cy = s.y + s.height / 2; - - if (this.sizers.length > 1) - { - this.moveSizerTo(this.sizers[0], s.x, s.y); - this.moveSizerTo(this.sizers[1], cx, s.y); - this.moveSizerTo(this.sizers[2], r, s.y); - this.moveSizerTo(this.sizers[3], s.x, cy); - this.moveSizerTo(this.sizers[4], r, cy); - this.moveSizerTo(this.sizers[5], s.x, b); - this.moveSizerTo(this.sizers[6], cx, b); - this.moveSizerTo(this.sizers[7], r, b); - this.moveSizerTo(this.sizers[8], - cx + s.absoluteOffset.x, - cy + s.absoluteOffset.y); - } - else if (this.state.width >= 2 && this.state.height >= 2) - { - this.moveSizerTo(this.sizers[0], - cx + s.absoluteOffset.x, - cy + s.absoluteOffset.y); - } - else - { - this.moveSizerTo(this.sizers[0], s.x, s.y); - } - } - } - - this.drawPreview(); -}; - -/** - * Function: drawPreview - * - * Redraws the preview. - */ -mxVertexHandler.prototype.drawPreview = function() -{ - if (this.preview != null) - { - this.preview.bounds = this.bounds; - - if (this.preview.node.parentNode == this.graph.container) - { - this.preview.bounds.width = Math.max(0, this.preview.bounds.width - 1); - this.preview.bounds.height = Math.max(0, this.preview.bounds.height - 1); - } - - this.preview.redraw(); - } - - this.selectionBorder.bounds = this.bounds; - this.selectionBorder.redraw(); -}; - -/** - * Function: destroy - * - * Destroys the handler and all its resources and DOM nodes. - */ -mxVertexHandler.prototype.destroy = function() -{ - if (this.preview != null) - { - this.preview.destroy(); - this.preview = null; - } - - this.selectionBorder.destroy(); - this.selectionBorder = null; - this.labelShape = null; - - if (this.sizers != null) - { - for (var i = 0; i < this.sizers.length; i++) - { - this.sizers[i].destroy(); - this.sizers[i] = null; - } - } -}; diff --git a/src/js/index.txt b/src/js/index.txt deleted file mode 100644 index f3631d6..0000000 --- a/src/js/index.txt +++ /dev/null @@ -1,316 +0,0 @@ -Document: API Specification - -Overview: - - This JavaScript library is divided into 8 packages. The top-level - class includes (or dynamically imports) everything else. The current version - is stored in . - - The *editor* package provides the classes required to implement a diagram - editor. The main class in this package is . - - The *view* and *model* packages implement the graph component, represented - by . It refers to a which contains s and - caches the state of the cells in a . The cells are painted - using a based on the appearance defined in . - Undo history is implemented in . To display an icon on the - graph, may be used. Validation rules are defined with - . - - The *handler*, *layout* and *shape* packages contain event listeners, - layout algorithms and shapes, respectively. The graph event listeners - include for rubberband selection, - for tooltips and for basic cell modifications. - implements a tree layout algorithm, and the - shape package provides various shapes, which are subclasses of - . - - The *util* package provides utility classes including for - copy-paste, for drag-and-drop, for keys and - values of stylesheets, and for cross-browser - event-handling and general purpose functions, for - internationalization and for console output. - - The *io* package implements a generic for turning - JavaScript objects into XML. The main class is . - is the global registry for custom codecs. - -Events: - - There are three different types of events, namely native DOM events, - which are fired in an , and - which are fired in . - - Some helper methods for handling native events are provided in . It - also takes care of resolving cycles between DOM nodes and JavaScript event - handlers, which can lead to memory leaks in IE6. - - Most custom events in mxGraph are implemented using . Its - listeners are functions that take a sender and . Additionally, - the class fires special which are handled using - mouse listeners, which are objects that provide a mousedown, mousemove and - mouseup method. - - Events in are fired using . - Listeners are added and removed using and - . in are fired using - . Listeners are added and removed using - and , respectively. - -Key bindings: - - The following key bindings are defined for mouse events in the client across - all browsers and platforms: - - - Control-Drag: Duplicates (clones) selected cells - - Shift-Rightlick: Shows the context menu - - Alt-Click: Forces rubberband (aka. marquee) - - Control-Select: Toggles the selection state - - Shift-Drag: Constrains the offset to one direction - - Shift-Control-Drag: Panning (also Shift-Rightdrag) - -Configuration: - - The following global variables may be defined before the client is loaded to - specify its language or base path, respectively. - - - mxBasePath: Specifies the path in . - - mxImageBasePath: Specifies the path in . - - mxLanguage: Specifies the language for resources in . - - mxDefaultLanguage: Specifies the default language in . - - mxLoadResources: Specifies if any resources should be loaded. Default is true. - - mxLoadStylesheets: Specifies if any stylesheets should be loaded. Default is true. - -Reserved Words: - - The mx prefix is used for all classes and objects in mxGraph. The mx prefix - can be seen as the global namespace for all JavaScript code in mxGraph. The - following fieldnames should not be used in objects. - - - *mxObjectId*: If the object is used with mxObjectIdentity - - *as*: If the object is a field of another object - - *id*: If the object is an idref in a codec - - *mxListenerList*: Added to DOM nodes when used with - - *window._mxDynamicCode*: Temporarily used to load code in Safari and Chrome - (see ). - - *_mxJavaScriptExpression*: Global variable that is temporarily used to - evaluate code in Safari, Opera, Firefox 3 and IE (see ). - -Files: - - The library contains these relative filenames. All filenames are relative - to . - -Built-in Images: - - All images are loaded from the , - which you can change to reflect your environment. The image variables can - also be changed individually. - - - mxGraph.prototype.collapsedImage - - mxGraph.prototype.expandedImage - - mxGraph.prototype.warningImage - - mxWindow.prototype.closeImage - - mxWindow.prototype.minimizeImage - - mxWindow.prototype.normalizeImage - - mxWindow.prototype.maximizeImage - - mxWindow.prototype.resizeImage - - mxPopupMenu.prototype.submenuImage - - mxUtils.errorImage - - mxConstraintHandler.prototype.pointImage - - The basename of the warning image (images/warning without extension) used in - is defined in . - -Resources: - - The and classes add the following resources to - at class loading time: - - - resources/editor*.properties - - resources/graph*.properties - - By default, the library ships with English and German resource files. - -Images: - - Recommendations for using images. Use GIF images (256 color palette) in HTML - elements (such as the toolbar and context menu), and PNG images (24 bit) for - all images which appear inside the graph component. - - - For PNG images inside HTML elements, Internet Explorer will ignore any - transparency information. - - For GIF images inside the graph, Firefox on the Mac will display strange - colors. Furthermore, only the first image for animated GIFs is displayed - on the Mac. - - For faster image rendering during application runtime, images can be - prefetched using the following code: - - (code) - var image = new Image(); - image.src = url_to_image; - (end) - -Deployment: - - The client is added to the page using the following script tag inside the - head of a document: - - (code) - - (end) - - The deployment version of the mxClient.js file contains all required code - in a single file. For deployment, the complete javascript/src directory is - required. - -Source Code: - - If you are a source code customer and you wish to develop using the - full source code, the commented source code is shipped in the - javascript/devel/source.zip file. It contains one file for each class - in mxGraph. To use the source code the source.zip file must be - uncompressed and the mxClient.js URL in the HTML page must be changed - to reference the uncompressed mxClient.js from the source.zip file. - -Compression: - - When using Apache2 with mod_deflate, you can use the following directive - in src/js/.htaccess to speedup the loading of the JavaScript sources: - - (code) - SetOutputFilter DEFLATE - (end) - -Classes: - - There are two types of "classes" in mxGraph: classes and singletons (where - only one instance exists). Singletons are mapped to global objects where the - variable name equals the classname. For example mxConstants is an object with - all the constants defined as object fields. Normal classes are mapped to a - constructor function and a prototype which defines the instance fields and - methods. For example, is a function and mxEditor.prototype is the - prototype for the object that the mxEditor function creates. The mx prefix is - a convention that is used for all classes in the mxGraph package to avoid - conflicts with other objects in the global namespace. - -Subclassing: - - For subclassing, the superclass must provide a constructor that is either - parameterless or handles an invocation with no arguments. Furthermore, the - special constructor field must be redefined after extending the prototype. - For example, the superclass of mxEditor is . This is - represented in JavaScript by first "inheriting" all fields and methods from - the superclass by assigning the prototype to an instance of the superclass, - eg. mxEditor.prototype = new mxEventSource() and redefining the constructor - field using mxEditor.prototype.constructor = mxEditor. The latter rule is - applied so that the type of an object can be retrieved via the name of it’s - constructor using mxUtils.getFunctionName(obj.constructor). - -Constructor: - - For subclassing in mxGraph, the same scheme should be applied. For example, - for subclassing the class, first a constructor must be defined for - the new class. The constructor calls the super constructor with any arguments - that it may have using the call function on the mxGraph function object, - passing along explitely each argument: - - (code) - function MyGraph(container) - { - mxGraph.call(this, container); - } - (end) - - The prototype of MyGraph inherits from mxGraph as follows. As usual, the - constructor is redefined after extending the superclass: - - (code) - MyGraph.prototype = new mxGraph(); - MyGraph.prototype.constructor = MyGraph; - (end) - - You may want to define the codec associated for the class after the above - code. This code will be executed at class loading time and makes sure the - same codec is used to encode instances of mxGraph and MyGraph. - - (code) - var codec = mxCodecRegistry.getCodec(mxGraph); - codec.template = new MyGraph(); - mxCodecRegistry.register(codec); - (end) - -Functions: - - In the prototype for MyGraph, functions of mxGraph can then be extended as - follows. - - (code) - MyGraph.prototype.isCellSelectable = function(cell) - { - var selectable = mxGraph.prototype.isSelectable.apply(this, arguments); - - var geo = this.model.getGeometry(cell); - return selectable && (geo == null || !geo.relative); - } - (end) - - The supercall in the first line is optional. It is done using the apply - function on the isSelectable function object of the mxGraph prototype, using - the special this and arguments variables as parameters. Calls to the - superclass function are only possible if the function is not replaced in the - superclass as follows, which is another way of “subclassing” in JavaScript. - - (code) - mxGraph.prototype.isCellSelectable = function(cell) - { - var geo = this.model.getGeometry(cell); - return selectable && - (geo == null || - !geo.relative); - } - (end) - - The above scheme is useful if a function definition needs to be replaced - completely. - - In order to add new functions and fields to the subclass, the following code - is used. The example below adds a new function to return the XML - representation of the graph model: - - (code) - MyGraph.prototype.getXml = function() - { - var enc = new mxCodec(); - return enc.encode(this.getModel()); - } - (end) - -Variables: - - Likewise, a new field is declared and defined as follows. - - (code) - MyGraph.prototype.myField = 'Hello, World!'; - (end) - - Note that the value assigned to myField is created only once, that is, all - instances of MyGraph share the same value. If you require instance-specific - values, then the field must be defined in the constructor instead. - - (code) - function MyGraph(container) - { - mxGraph.call(this, container); - - this.myField = new Array(); - } - (end) - - Finally, a new instance of MyGraph is created using the following code, where - container is a DOM node that acts as a container for the graph view: - - (code) - var graph = new MyGraph(container); - (end) diff --git a/src/js/io/mxCellCodec.js b/src/js/io/mxCellCodec.js deleted file mode 100644 index cbcd651..0000000 --- a/src/js/io/mxCellCodec.js +++ /dev/null @@ -1,170 +0,0 @@ -/** - * $Id: mxCellCodec.js,v 1.22 2010-10-21 07:12:31 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -mxCodecRegistry.register(function() -{ - /** - * Class: mxCellCodec - * - * Codec for s. This class is created and registered - * dynamically at load time and used implicitely via - * and the . - * - * Transient Fields: - * - * - children - * - edges - * - overlays - * - mxTransient - * - * Reference Fields: - * - * - parent - * - source - * - target - * - * Transient fields can be added using the following code: - * - * mxCodecRegistry.getCodec(mxCell).exclude.push('name_of_field'); - */ - var codec = new mxObjectCodec(new mxCell(), - ['children', 'edges', 'overlays', 'mxTransient'], - ['parent', 'source', 'target']); - - /** - * Function: isCellCodec - * - * Returns true since this is a cell codec. - */ - codec.isCellCodec = function() - { - return true; - }; - - /** - * Function: isExcluded - * - * Excludes user objects that are XML nodes. - */ - codec.isExcluded = function(obj, attr, value, isWrite) - { - return mxObjectCodec.prototype.isExcluded.apply(this, arguments) || - (isWrite && attr == 'value' && - value.nodeType == mxConstants.NODETYPE_ELEMENT); - }; - - /** - * Function: afterEncode - * - * Encodes an and wraps the XML up inside the - * XML of the user object (inversion). - */ - codec.afterEncode = function(enc, obj, node) - { - if (obj.value != null && - obj.value.nodeType == mxConstants.NODETYPE_ELEMENT) - { - // Wraps the graphical annotation up in the user object (inversion) - // by putting the result of the default encoding into a clone of the - // user object (node type 1) and returning this cloned user object. - var tmp = node; - node = (mxClient.IS_IE) ? - obj.value.cloneNode(true) : - enc.document.importNode(obj.value, true); - node.appendChild(tmp); - - // Moves the id attribute to the outermost XML node, namely the - // node which denotes the object boundaries in the file. - var id = tmp.getAttribute('id'); - node.setAttribute('id', id); - tmp.removeAttribute('id'); - } - - return node; - }; - - /** - * Function: beforeDecode - * - * Decodes an and uses the enclosing XML node as - * the user object for the cell (inversion). - */ - codec.beforeDecode = function(dec, node, obj) - { - var inner = node; - var classname = this.getName(); - - if (node.nodeName != classname) - { - // Passes the inner graphical annotation node to the - // object codec for further processing of the cell. - var tmp = node.getElementsByTagName(classname)[0]; - - if (tmp != null && - tmp.parentNode == node) - { - mxUtils.removeWhitespace(tmp, true); - mxUtils.removeWhitespace(tmp, false); - tmp.parentNode.removeChild(tmp); - inner = tmp; - } - else - { - inner = null; - } - - // Creates the user object out of the XML node - obj.value = node.cloneNode(true); - var id = obj.value.getAttribute('id'); - - if (id != null) - { - obj.setId(id); - obj.value.removeAttribute('id'); - } - } - else - { - // Uses ID from XML file as ID for cell in model - obj.setId(node.getAttribute('id')); - } - - // Preprocesses and removes all Id-references in order to use the - // correct encoder (this) for the known references to cells (all). - if (inner != null) - { - for (var i = 0; i < this.idrefs.length; i++) - { - var attr = this.idrefs[i]; - var ref = inner.getAttribute(attr); - - if (ref != null) - { - inner.removeAttribute(attr); - var object = dec.objects[ref] || dec.lookup(ref); - - if (object == null) - { - // Needs to decode forward reference - var element = dec.getElementById(ref); - - if (element != null) - { - var decoder = mxCodecRegistry.codecs[element.nodeName] || this; - object = decoder.decode(dec, element); - } - } - - obj[attr] = object; - } - } - } - - return inner; - }; - - // Returns the codec into the registry - return codec; - -}()); diff --git a/src/js/io/mxChildChangeCodec.js b/src/js/io/mxChildChangeCodec.js deleted file mode 100644 index deeb57b..0000000 --- a/src/js/io/mxChildChangeCodec.js +++ /dev/null @@ -1,149 +0,0 @@ -/** - * $Id: mxChildChangeCodec.js,v 1.12 2010-09-15 14:38:52 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -mxCodecRegistry.register(function() -{ - /** - * Class: mxChildChangeCodec - * - * Codec for s. This class is created and registered - * dynamically at load time and used implicitely via and - * the . - * - * Transient Fields: - * - * - model - * - previous - * - previousIndex - * - child - * - * Reference Fields: - * - * - parent - */ - var codec = new mxObjectCodec(new mxChildChange(), - ['model', 'child', 'previousIndex'], - ['parent', 'previous']); - - /** - * Function: isReference - * - * Returns true for the child attribute if the child - * cell had a previous parent or if we're reading the - * child as an attribute rather than a child node, in - * which case it's always a reference. - */ - codec.isReference = function(obj, attr, value, isWrite) - { - if (attr == 'child' && - (obj.previous != null || - !isWrite)) - { - return true; - } - - return mxUtils.indexOf(this.idrefs, attr) >= 0; - }; - - /** - * Function: afterEncode - * - * Encodes the child recusively and adds the result - * to the given node. - */ - codec.afterEncode = function(enc, obj, node) - { - if (this.isReference(obj, 'child', obj.child, true)) - { - // Encodes as reference (id) - node.setAttribute('child', enc.getId(obj.child)); - } - else - { - // At this point, the encoder is no longer able to know which cells - // are new, so we have to encode the complete cell hierarchy and - // ignore the ones that are already there at decoding time. Note: - // This can only be resolved by moving the notify event into the - // execute of the edit. - enc.encodeCell(obj.child, node); - } - - return node; - }; - - /** - * Function: beforeDecode - * - * Decodes the any child nodes as using the respective - * codec from the registry. - */ - codec.beforeDecode = function(dec, node, obj) - { - if (node.firstChild != null && - node.firstChild.nodeType == mxConstants.NODETYPE_ELEMENT) - { - // Makes sure the original node isn't modified - node = node.cloneNode(true); - - var tmp = node.firstChild; - obj.child = dec.decodeCell(tmp, false); - - var tmp2 = tmp.nextSibling; - tmp.parentNode.removeChild(tmp); - tmp = tmp2; - - while (tmp != null) - { - tmp2 = tmp.nextSibling; - - if (tmp.nodeType == mxConstants.NODETYPE_ELEMENT) - { - // Ignores all existing cells because those do not need to - // be re-inserted into the model. Since the encoded version - // of these cells contains the new parent, this would leave - // to an inconsistent state on the model (ie. a parent - // change without a call to parentForCellChanged). - var id = tmp.getAttribute('id'); - - if (dec.lookup(id) == null) - { - dec.decodeCell(tmp); - } - } - - tmp.parentNode.removeChild(tmp); - tmp = tmp2; - } - } - else - { - var childRef = node.getAttribute('child'); - obj.child = dec.getObject(childRef); - } - - return node; - }; - - /** - * Function: afterDecode - * - * Restores object state in the child change. - */ - codec.afterDecode = function(dec, node, obj) - { - // Cells are encoded here after a complete transaction so the previous - // parent must be restored on the cell for the case where the cell was - // added. This is needed for the local model to identify the cell as a - // new cell and register the ID. - obj.child.parent = obj.previous; - obj.previous = obj.parent; - obj.previousIndex = obj.index; - - return obj; - }; - - // Returns the codec into the registry - return codec; - -}()); diff --git a/src/js/io/mxCodec.js b/src/js/io/mxCodec.js deleted file mode 100644 index b8bfc6a..0000000 --- a/src/js/io/mxCodec.js +++ /dev/null @@ -1,531 +0,0 @@ -/** - * $Id: mxCodec.js,v 1.48 2012-01-04 10:01:16 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxCodec - * - * XML codec for JavaScript object graphs. See for a - * description of the general encoding/decoding scheme. This class uses the - * codecs registered in for encoding/decoding each object. - * - * References: - * - * In order to resolve references, especially forward references, the mxCodec - * constructor must be given the document that contains the referenced - * elements. - * - * Examples: - * - * The following code is used to encode a graph model. - * - * (code) - * var encoder = new mxCodec(); - * var result = encoder.encode(graph.getModel()); - * var xml = mxUtils.getXml(result); - * (end) - * - * Example: - * - * Using the following code, the selection cells of a graph are encoded and the - * output is displayed in a dialog box. - * - * (code) - * var enc = new mxCodec(); - * var cells = graph.getSelectionCells(); - * mxUtils.alert(mxUtils.getPrettyXml(enc.encode(cells))); - * (end) - * - * Newlines in the XML can be coverted to
, in which case a '
' argument - * must be passed to as the second argument. - * - * Example: - * - * Using the code below, an XML document is decodec into an existing model. The - * document may be obtained using one of the functions in mxUtils for loading - * an XML file, eg. , or using for parsing an - * XML string. - * - * (code) - * var decoder = new mxCodec(doc) - * decoder.decode(doc.documentElement, graph.getModel()); - * (end) - * - * Debugging: - * - * For debugging i/o you can use the following code to get the sequence of - * encoded objects: - * - * (code) - * var oldEncode = mxCodec.prototype.encode; - * mxCodec.prototype.encode = function(obj) - * { - * mxLog.show(); - * mxLog.debug('mxCodec.encode: obj='+mxUtils.getFunctionName(obj.constructor)); - * - * return oldEncode.apply(this, arguments); - * }; - * (end) - * - * Constructor: mxCodec - * - * Constructs an XML encoder/decoder for the specified - * owner document. - * - * Parameters: - * - * document - Optional XML document that contains the data. - * If no document is specified then a new document is created - * using . - */ -function mxCodec(document) -{ - this.document = document || mxUtils.createXmlDocument(); - this.objects = []; -}; - -/** - * Variable: document - * - * The owner document of the codec. - */ -mxCodec.prototype.document = null; - -/** - * Variable: objects - * - * Maps from IDs to objects. - */ -mxCodec.prototype.objects = null; - -/** - * Variable: encodeDefaults - * - * Specifies if default values should be encoded. Default is false. - */ -mxCodec.prototype.encodeDefaults = false; - - -/** - * Function: putObject - * - * Assoiates the given object with the given ID and returns the given object. - * - * Parameters - * - * id - ID for the object to be associated with. - * obj - Object to be associated with the ID. - */ -mxCodec.prototype.putObject = function(id, obj) -{ - this.objects[id] = obj; - - return obj; -}; - -/** - * Function: getObject - * - * Returns the decoded object for the element with the specified ID in - * . If the object is not known then is used to find an - * object. If no object is found, then the element with the respective ID - * from the document is parsed using . - */ -mxCodec.prototype.getObject = function(id) -{ - var obj = null; - - if (id != null) - { - obj = this.objects[id]; - - if (obj == null) - { - obj = this.lookup(id); - - if (obj == null) - { - var node = this.getElementById(id); - - if (node != null) - { - obj = this.decode(node); - } - } - } - } - - return obj; -}; - -/** - * Function: lookup - * - * Hook for subclassers to implement a custom lookup mechanism for cell IDs. - * This implementation always returns null. - * - * Example: - * - * (code) - * var codec = new mxCodec(); - * codec.lookup = function(id) - * { - * return model.getCell(id); - * }; - * (end) - * - * Parameters: - * - * id - ID of the object to be returned. - */ -mxCodec.prototype.lookup = function(id) -{ - return null; -}; - -/** - * Function: getElementById - * - * Returns the element with the given ID from . The optional attr - * argument specifies the name of the ID attribute. Default is "id". The - * XPath expression used to find the element is //*[@attr='arg'] where attr is - * the name of the ID attribute and arg is the given id. - * - * Parameters: - * - * id - String that contains the ID. - * attr - Optional string for the attributename. Default is "id". - */ -mxCodec.prototype.getElementById = function(id, attr) -{ - attr = (attr != null) ? attr : 'id'; - - return mxUtils.findNodeByAttribute(this.document.documentElement, attr, id); -}; - -/** - * Function: getId - * - * Returns the ID of the specified object. This implementation - * calls first and if that returns null handles - * the object as an by returning their IDs using - * . If no ID exists for the given cell, then - * an on-the-fly ID is generated using . - * - * Parameters: - * - * obj - Object to return the ID for. - */ -mxCodec.prototype.getId = function(obj) -{ - var id = null; - - if (obj != null) - { - id = this.reference(obj); - - if (id == null && obj instanceof mxCell) - { - id = obj.getId(); - - if (id == null) - { - // Uses an on-the-fly Id - id = mxCellPath.create(obj); - - if (id.length == 0) - { - id = 'root'; - } - } - } - } - - return id; -}; - -/** - * Function: reference - * - * Hook for subclassers to implement a custom method - * for retrieving IDs from objects. This implementation - * always returns null. - * - * Example: - * - * (code) - * var codec = new mxCodec(); - * codec.reference = function(obj) - * { - * return obj.getCustomId(); - * }; - * (end) - * - * Parameters: - * - * obj - Object whose ID should be returned. - */ -mxCodec.prototype.reference = function(obj) -{ - return null; -}; - -/** - * Function: encode - * - * Encodes the specified object and returns the resulting - * XML node. - * - * Parameters: - * - * obj - Object to be encoded. - */ -mxCodec.prototype.encode = function(obj) -{ - var node = null; - - if (obj != null && obj.constructor != null) - { - var enc = mxCodecRegistry.getCodec(obj.constructor); - - if (enc != null) - { - node = enc.encode(this, obj); - } - else - { - if (mxUtils.isNode(obj)) - { - node = (mxClient.IS_IE) ? obj.cloneNode(true) : - this.document.importNode(obj, true); - } - else - { - mxLog.warn('mxCodec.encode: No codec for '+ - mxUtils.getFunctionName(obj.constructor)); - } - } - } - - return node; -}; - -/** - * Function: decode - * - * Decodes the given XML node. The optional "into" - * argument specifies an existing object to be - * used. If no object is given, then a new instance - * is created using the constructor from the codec. - * - * The function returns the passed in object or - * the new instance if no object was given. - * - * Parameters: - * - * node - XML node to be decoded. - * into - Optional object to be decodec into. - */ -mxCodec.prototype.decode = function(node, into) -{ - var obj = null; - - if (node != null && node.nodeType == mxConstants.NODETYPE_ELEMENT) - { - var ctor = null; - - try - { - ctor = eval(node.nodeName); - } - catch (err) - { - // ignore - } - - try - { - var dec = mxCodecRegistry.getCodec(ctor); - - if (dec != null) - { - obj = dec.decode(this, node, into); - } - else - { - obj = node.cloneNode(true); - obj.removeAttribute('as'); - } - } - catch (err) - { - mxLog.debug('Cannot decode '+node.nodeName+': '+err.message); - } - } - - return obj; -}; - -/** - * Function: encodeCell - * - * Encoding of cell hierarchies is built-into the core, but - * is a higher-level function that needs to be explicitely - * used by the respective object encoders (eg. , - * and ). This - * implementation writes the given cell and its children as a - * (flat) sequence into the given node. The children are not - * encoded if the optional includeChildren is false. The - * function is in charge of adding the result into the - * given node and has no return value. - * - * Parameters: - * - * cell - to be encoded. - * node - Parent XML node to add the encoded cell into. - * includeChildren - Optional boolean indicating if the - * function should include all descendents. Default is true. - */ -mxCodec.prototype.encodeCell = function(cell, node, includeChildren) -{ - node.appendChild(this.encode(cell)); - - if (includeChildren == null || includeChildren) - { - var childCount = cell.getChildCount(); - - for (var i = 0; i < childCount; i++) - { - this.encodeCell(cell.getChildAt(i), node); - } - } -}; - -/** - * Function: isCellCodec - * - * Returns true if the given codec is a cell codec. This uses - * to check if the codec is of the - * given type. - */ -mxCodec.prototype.isCellCodec = function(codec) -{ - if (codec != null && typeof(codec.isCellCodec) == 'function') - { - return codec.isCellCodec(); - } - - return false; -}; - -/** - * Function: decodeCell - * - * Decodes cells that have been encoded using inversion, ie. - * where the user object is the enclosing node in the XML, - * and restores the group and graph structure in the cells. - * Returns a new instance that represents the - * given node. - * - * Parameters: - * - * node - XML node that contains the cell data. - * restoreStructures - Optional boolean indicating whether - * the graph structure should be restored by calling insert - * and insertEdge on the parent and terminals, respectively. - * Default is true. - */ -mxCodec.prototype.decodeCell = function(node, restoreStructures) -{ - restoreStructures = (restoreStructures != null) ? restoreStructures : true; - var cell = null; - - if (node != null && node.nodeType == mxConstants.NODETYPE_ELEMENT) - { - // Tries to find a codec for the given node name. If that does - // not return a codec then the node is the user object (an XML node - // that contains the mxCell, aka inversion). - var decoder = mxCodecRegistry.getCodec(node.nodeName); - - // Tries to find the codec for the cell inside the user object. - // This assumes all node names inside the user object are either - // not registered or they correspond to a class for cells. - if (!this.isCellCodec(decoder)) - { - var child = node.firstChild; - - while (child != null && !this.isCellCodec(decoder)) - { - decoder = mxCodecRegistry.getCodec(child.nodeName); - child = child.nextSibling; - } - } - - if (!this.isCellCodec(decoder)) - { - decoder = mxCodecRegistry.getCodec(mxCell); - } - - cell = decoder.decode(this, node); - - if (restoreStructures) - { - this.insertIntoGraph(cell); - } - } - - return cell; -}; - -/** - * Function: insertIntoGraph - * - * Inserts the given cell into its parent and terminal cells. - */ -mxCodec.prototype.insertIntoGraph = function(cell) -{ - var parent = cell.parent; - var source = cell.getTerminal(true); - var target = cell.getTerminal(false); - - // Fixes possible inconsistencies during insert into graph - cell.setTerminal(null, false); - cell.setTerminal(null, true); - cell.parent = null; - - if (parent != null) - { - parent.insert(cell); - } - - if (source != null) - { - source.insertEdge(cell, true); - } - - if (target != null) - { - target.insertEdge(cell, false); - } -}; - -/** - * Function: setAttribute - * - * Sets the attribute on the specified node to value. This is a - * helper method that makes sure the attribute and value arguments - * are not null. - * - * Parameters: - * - * node - XML node to set the attribute for. - * attributes - Attributename to be set. - * value - New value of the attribute. - */ -mxCodec.prototype.setAttribute = function(node, attribute, value) -{ - if (attribute != null && value != null) - { - node.setAttribute(attribute, value); - } -}; diff --git a/src/js/io/mxCodecRegistry.js b/src/js/io/mxCodecRegistry.js deleted file mode 100644 index a0a0f20..0000000 --- a/src/js/io/mxCodecRegistry.js +++ /dev/null @@ -1,137 +0,0 @@ -/** - * $Id: mxCodecRegistry.js,v 1.12 2010-04-30 13:18:21 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -var mxCodecRegistry = -{ - /** - * Class: mxCodecRegistry - * - * Singleton class that acts as a global registry for codecs. - * - * Adding an : - * - * 1. Define a default codec with a new instance of the - * object to be handled. - * - * (code) - * var codec = new mxObjectCodec(new mxGraphModel()); - * (end) - * - * 2. Define the functions required for encoding and decoding - * objects. - * - * (code) - * codec.encode = function(enc, obj) { ... } - * codec.decode = function(dec, node, into) { ... } - * (end) - * - * 3. Register the codec in the . - * - * (code) - * mxCodecRegistry.register(codec); - * (end) - * - * may be used to either create a new - * instance of an object or to configure an existing instance, - * in which case the into argument points to the existing - * object. In this case, we say the codec "configures" the - * object. - * - * Variable: codecs - * - * Maps from constructor names to codecs. - */ - codecs: [], - - /** - * Variable: aliases - * - * Maps from classnames to codecnames. - */ - aliases: [], - - /** - * Function: register - * - * Registers a new codec and associates the name of the template - * constructor in the codec with the codec object. - * - * Parameters: - * - * codec - to be registered. - */ - register: function(codec) - { - if (codec != null) - { - var name = codec.getName(); - mxCodecRegistry.codecs[name] = codec; - - var classname = mxUtils.getFunctionName(codec.template.constructor); - - if (classname != name) - { - mxCodecRegistry.addAlias(classname, name); - } - } - - return codec; - }, - - /** - * Function: addAlias - * - * Adds an alias for mapping a classname to a codecname. - */ - addAlias: function(classname, codecname) - { - mxCodecRegistry.aliases[classname] = codecname; - }, - - /** - * Function: getCodec - * - * Returns a codec that handles objects that are constructed - * using the given constructor. - * - * Parameters: - * - * ctor - JavaScript constructor function. - */ - getCodec: function(ctor) - { - var codec = null; - - if (ctor != null) - { - var name = mxUtils.getFunctionName(ctor); - var tmp = mxCodecRegistry.aliases[name]; - - if (tmp != null) - { - name = tmp; - } - - codec = mxCodecRegistry.codecs[name]; - - // Registers a new default codec for the given constructor - // if no codec has been previously defined. - if (codec == null) - { - try - { - codec = new mxObjectCodec(new ctor()); - mxCodecRegistry.register(codec); - } - catch (e) - { - // ignore - } - } - } - - return codec; - } - -}; diff --git a/src/js/io/mxDefaultKeyHandlerCodec.js b/src/js/io/mxDefaultKeyHandlerCodec.js deleted file mode 100644 index 628524a..0000000 --- a/src/js/io/mxDefaultKeyHandlerCodec.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * $Id: mxDefaultKeyHandlerCodec.js,v 1.5 2010-01-02 09:45:15 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -mxCodecRegistry.register(function() -{ - /** - * Class: mxDefaultKeyHandlerCodec - * - * Custom codec for configuring s. This class is created - * and registered dynamically at load time and used implicitely via - * and the . This codec only reads configuration - * data for existing key handlers, it does not encode or create key handlers. - */ - var codec = new mxObjectCodec(new mxDefaultKeyHandler()); - - /** - * Function: encode - * - * Returns null. - */ - codec.encode = function(enc, obj) - { - return null; - }; - - /** - * Function: decode - * - * Reads a sequence of the following child nodes - * and attributes: - * - * Child Nodes: - * - * add - Binds a keystroke to an actionname. - * - * Attributes: - * - * as - Keycode. - * action - Actionname to execute in editor. - * control - Optional boolean indicating if - * the control key must be pressed. - * - * Example: - * - * (code) - * - * - * - * - * - * (end) - * - * The keycodes are for the x, c and v keys. - * - * See also: , - * http://www.js-examples.com/page/tutorials__key_codes.html - */ - codec.decode = function(dec, node, into) - { - if (into != null) - { - var editor = into.editor; - node = node.firstChild; - - while (node != null) - { - if (!this.processInclude(dec, node, into) && - node.nodeName == 'add') - { - var as = node.getAttribute('as'); - var action = node.getAttribute('action'); - var control = node.getAttribute('control'); - - into.bindAction(as, action, control); - } - - node = node.nextSibling; - } - } - - return into; - }; - - // Returns the codec into the registry - return codec; - -}()); diff --git a/src/js/io/mxDefaultPopupMenuCodec.js b/src/js/io/mxDefaultPopupMenuCodec.js deleted file mode 100644 index 8d949ea..0000000 --- a/src/js/io/mxDefaultPopupMenuCodec.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * $Id: mxDefaultPopupMenuCodec.js,v 1.6 2010-01-02 09:45:15 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -mxCodecRegistry.register(function() -{ - /** - * Class: mxDefaultPopupMenuCodec - * - * Custom codec for configuring s. This class is created - * and registered dynamically at load time and used implicitely via - * and the . This codec only reads configuration - * data for existing popup menus, it does not encode or create menus. Note - * that this codec only passes the configuration node to the popup menu, - * which uses the config to dynamically create menus. See - * . - */ - var codec = new mxObjectCodec(new mxDefaultPopupMenu()); - - /** - * Function: encode - * - * Returns null. - */ - codec.encode = function(enc, obj) - { - return null; - }; - - /** - * Function: decode - * - * Uses the given node as the config for . - */ - codec.decode = function(dec, node, into) - { - var inc = node.getElementsByTagName('include')[0]; - - if (inc != null) - { - this.processInclude(dec, inc, into); - } - else if (into != null) - { - into.config = node; - } - - return into; - }; - - // Returns the codec into the registry - return codec; - -}()); diff --git a/src/js/io/mxDefaultToolbarCodec.js b/src/js/io/mxDefaultToolbarCodec.js deleted file mode 100644 index 6698b9b..0000000 --- a/src/js/io/mxDefaultToolbarCodec.js +++ /dev/null @@ -1,301 +0,0 @@ -/** - * $Id: mxDefaultToolbarCodec.js,v 1.22 2012-04-11 07:00:52 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -mxCodecRegistry.register(function() -{ - /** - * Class: mxDefaultToolbarCodec - * - * Custom codec for configuring s. This class is created - * and registered dynamically at load time and used implicitely via - * and the . This codec only reads configuration - * data for existing toolbars handlers, it does not encode or create toolbars. - */ - var codec = new mxObjectCodec(new mxDefaultToolbar()); - - /** - * Function: encode - * - * Returns null. - */ - codec.encode = function(enc, obj) - { - return null; - }; - - /** - * Function: decode - * - * Reads a sequence of the following child nodes - * and attributes: - * - * Child Nodes: - * - * add - Adds a new item to the toolbar. See below for attributes. - * separator - Adds a vertical separator. No attributes. - * hr - Adds a horizontal separator. No attributes. - * br - Adds a linefeed. No attributes. - * - * Attributes: - * - * as - Resource key for the label. - * action - Name of the action to execute in enclosing editor. - * mode - Modename (see below). - * template - Template name for cell insertion. - * style - Optional style to override the template style. - * icon - Icon (relative/absolute URL). - * pressedIcon - Optional icon for pressed state (relative/absolute URL). - * id - Optional ID to be used for the created DOM element. - * toggle - Optional 0 or 1 to disable toggling of the element. Default is - * 1 (true). - * - * The action, mode and template attributes are mutually exclusive. The - * style can only be used with the template attribute. The add node may - * contain another sequence of add nodes with as and action attributes - * to create a combo box in the toolbar. If the icon is specified then - * a list of the child node is expected to have its template attribute - * set and the action is ignored instead. - * - * Nodes with a specified template may define a function to be used for - * inserting the cloned template into the graph. Here is an example of such - * a node: - * - * (code) - * - * (end) - * - * In the above function, editor is the enclosing instance, cell - * is the clone of the template, evt is the mouse event that represents the - * drop and targetCell is the cell under the mousepointer where the drop - * occurred. The targetCell is retrieved using . - * - * Futhermore, nodes with the mode attribute may define a function to - * be executed upon selection of the respective toolbar icon. In the - * example below, the default edge style is set when this specific - * connect-mode is activated: - * - * (code) - * - * (end) - * - * Modes: - * - * select - Left mouse button used for rubberband- & cell-selection. - * connect - Allows connecting vertices by inserting new edges. - * pan - Disables selection and switches to panning on the left button. - * - * Example: - * - * To add items to the toolbar: - * - * (code) - * - * - *

- * - * - *
- * (end) - */ - codec.decode = function(dec, node, into) - { - if (into != null) - { - var editor = into.editor; - node = node.firstChild; - - while (node != null) - { - if (node.nodeType == mxConstants.NODETYPE_ELEMENT) - { - if (!this.processInclude(dec, node, into)) - { - if (node.nodeName == 'separator') - { - into.addSeparator(); - } - else if (node.nodeName == 'br') - { - into.toolbar.addBreak(); - } - else if (node.nodeName == 'hr') - { - into.toolbar.addLine(); - } - else if (node.nodeName == 'add') - { - var as = node.getAttribute('as'); - as = mxResources.get(as) || as; - var icon = node.getAttribute('icon'); - var pressedIcon = node.getAttribute('pressedIcon'); - var action = node.getAttribute('action'); - var mode = node.getAttribute('mode'); - var template = node.getAttribute('template'); - var toggle = node.getAttribute('toggle') != '0'; - var text = mxUtils.getTextContent(node); - var elt = null; - - if (action != null) - { - elt = into.addItem(as, icon, action, pressedIcon); - } - else if (mode != null) - { - var funct = mxUtils.eval(text); - elt = into.addMode(as, icon, mode, pressedIcon, funct); - } - else if (template != null || (text != null && text.length > 0)) - { - var cell = editor.templates[template]; - var style = node.getAttribute('style'); - - if (cell != null && style != null) - { - cell = cell.clone(); - cell.setStyle(style); - } - - var insertFunction = null; - - if (text != null && text.length > 0) - { - insertFunction = mxUtils.eval(text); - } - - elt = into.addPrototype(as, icon, cell, pressedIcon, insertFunction, toggle); - } - else - { - var children = mxUtils.getChildNodes(node); - - if (children.length > 0) - { - if (icon == null) - { - var combo = into.addActionCombo(as); - - for (var i=0; i 0) - { - elt.setAttribute('id', id); - } - } - } - } - } - - node = node.nextSibling; - } - } - - return into; - }; - - // Returns the codec into the registry - return codec; - -}()); diff --git a/src/js/io/mxEditorCodec.js b/src/js/io/mxEditorCodec.js deleted file mode 100644 index f61bd95..0000000 --- a/src/js/io/mxEditorCodec.js +++ /dev/null @@ -1,246 +0,0 @@ -/** - * $Id: mxEditorCodec.js,v 1.11 2010-01-04 11:18:26 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -mxCodecRegistry.register(function() -{ - /** - * Class: mxEditorCodec - * - * Codec for s. This class is created and registered - * dynamically at load time and used implicitely via - * and the . - * - * Transient Fields: - * - * - modified - * - lastSnapshot - * - ignoredChanges - * - undoManager - * - graphContainer - * - toolbarContainer - */ - var codec = new mxObjectCodec(new mxEditor(), - ['modified', 'lastSnapshot', 'ignoredChanges', - 'undoManager', 'graphContainer', 'toolbarContainer']); - - /** - * Function: beforeDecode - * - * Decodes the ui-part of the configuration node by reading - * a sequence of the following child nodes and attributes - * and passes the control to the default decoding mechanism: - * - * Child Nodes: - * - * stylesheet - Adds a CSS stylesheet to the document. - * resource - Adds the basename of a resource bundle. - * add - Creates or configures a known UI element. - * - * These elements may appear in any order given that the - * graph UI element is added before the toolbar element - * (see Known Keys). - * - * Attributes: - * - * as - Key for the UI element (see below). - * element - ID for the element in the document. - * style - CSS style to be used for the element or window. - * x - X coordinate for the new window. - * y - Y coordinate for the new window. - * width - Width for the new window. - * height - Optional height for the new window. - * name - Name of the stylesheet (absolute/relative URL). - * basename - Basename of the resource bundle (see ). - * - * The x, y, width and height attributes are used to create a new - * if the element attribute is not specified in an add - * node. The name and basename are only used in the stylesheet and - * resource nodes, respectively. - * - * Known Keys: - * - * graph - Main graph element (see ). - * title - Title element (see ). - * toolbar - Toolbar element (see ). - * status - Status bar element (see ). - * - * Example: - * - * (code) - * - * - * - * - * - * - * - * (end) - */ - codec.afterDecode = function(dec, node, obj) - { - // Assigns the specified templates for edges - var defaultEdge = node.getAttribute('defaultEdge'); - - if (defaultEdge != null) - { - node.removeAttribute('defaultEdge'); - obj.defaultEdge = obj.templates[defaultEdge]; - } - - // Assigns the specified templates for groups - var defaultGroup = node.getAttribute('defaultGroup'); - - if (defaultGroup != null) - { - node.removeAttribute('defaultGroup'); - obj.defaultGroup = obj.templates[defaultGroup]; - } - - return obj; - }; - - /** - * Function: decodeChild - * - * Overrides decode child to handle special child nodes. - */ - codec.decodeChild = function(dec, child, obj) - { - if (child.nodeName == 'Array') - { - var role = child.getAttribute('as'); - - if (role == 'templates') - { - this.decodeTemplates(dec, child, obj); - return; - } - } - else if (child.nodeName == 'ui') - { - this.decodeUi(dec, child, obj); - return; - } - - mxObjectCodec.prototype.decodeChild.apply(this, arguments); - }; - - /** - * Function: decodeTemplates - * - * Decodes the cells from the given node as templates. - */ - codec.decodeUi = function(dec, node, editor) - { - var tmp = node.firstChild; - while (tmp != null) - { - if (tmp.nodeName == 'add') - { - var as = tmp.getAttribute('as'); - var elt = tmp.getAttribute('element'); - var style = tmp.getAttribute('style'); - var element = null; - - if (elt != null) - { - element = document.getElementById(elt); - - if (element != null && - style != null) - { - element.style.cssText += ';'+style; - } - } - else - { - var x = parseInt(tmp.getAttribute('x')); - var y = parseInt(tmp.getAttribute('y')); - var width = tmp.getAttribute('width'); - var height = tmp.getAttribute('height'); - - // Creates a new window around the element - element = document.createElement('div'); - element.style.cssText = style; - - var wnd = new mxWindow(mxResources.get(as) || as, - element, x, y, width, height, false, true); - wnd.setVisible(true); - } - - // TODO: Make more generic - if (as == 'graph') - { - editor.setGraphContainer(element); - } - else if (as == 'toolbar') - { - editor.setToolbarContainer(element); - } - else if (as == 'title') - { - editor.setTitleContainer(element); - } - else if (as == 'status') - { - editor.setStatusContainer(element); - } - else if (as == 'map') - { - editor.setMapContainer(element); - } - } - else if (tmp.nodeName == 'resource') - { - mxResources.add(tmp.getAttribute('basename')); - } - else if (tmp.nodeName == 'stylesheet') - { - mxClient.link('stylesheet', tmp.getAttribute('name')); - } - - tmp = tmp.nextSibling; - } - }; - - /** - * Function: decodeTemplates - * - * Decodes the cells from the given node as templates. - */ - codec.decodeTemplates = function(dec, node, editor) - { - if (editor.templates == null) - { - editor.templates = []; - } - - var children = mxUtils.getChildNodes(node); - for (var j=0; js, s, s, - * s and s. This class is created - * and registered dynamically at load time and used implicitely - * via and the . - * - * Transient Fields: - * - * - model - * - previous - * - * Reference Fields: - * - * - cell - * - * Constructor: mxGenericChangeCodec - * - * Factory function that creates a for - * the specified change and fieldname. - * - * Parameters: - * - * obj - An instance of the change object. - * variable - The fieldname for the change data. - */ -var mxGenericChangeCodec = function(obj, variable) -{ - var codec = new mxObjectCodec(obj, ['model', 'previous'], ['cell']); - - /** - * Function: afterDecode - * - * Restores the state by assigning the previous value. - */ - codec.afterDecode = function(dec, node, obj) - { - // Allows forward references in sessions. This is a workaround - // for the sequence of edits in mxGraph.moveCells and cellsAdded. - if (mxUtils.isNode(obj.cell)) - { - obj.cell = dec.decodeCell(obj.cell, false); - } - - obj.previous = obj[variable]; - - return obj; - }; - - return codec; -}; - -// Registers the codecs -mxCodecRegistry.register(mxGenericChangeCodec(new mxValueChange(), 'value')); -mxCodecRegistry.register(mxGenericChangeCodec(new mxStyleChange(), 'style')); -mxCodecRegistry.register(mxGenericChangeCodec(new mxGeometryChange(), 'geometry')); -mxCodecRegistry.register(mxGenericChangeCodec(new mxCollapseChange(), 'collapsed')); -mxCodecRegistry.register(mxGenericChangeCodec(new mxVisibleChange(), 'visible')); -mxCodecRegistry.register(mxGenericChangeCodec(new mxCellAttributeChange(), 'value')); diff --git a/src/js/io/mxGraphCodec.js b/src/js/io/mxGraphCodec.js deleted file mode 100644 index f052e13..0000000 --- a/src/js/io/mxGraphCodec.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * $Id: mxGraphCodec.js,v 1.8 2010-06-10 06:54:18 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -mxCodecRegistry.register(function() -{ - /** - * Class: mxGraphCodec - * - * Codec for s. This class is created and registered - * dynamically at load time and used implicitely via - * and the . - * - * Transient Fields: - * - * - graphListeners - * - eventListeners - * - view - * - container - * - cellRenderer - * - editor - * - selection - */ - return new mxObjectCodec(new mxGraph(), - ['graphListeners', 'eventListeners', 'view', 'container', - 'cellRenderer', 'editor', 'selection']); - -}()); diff --git a/src/js/io/mxGraphViewCodec.js b/src/js/io/mxGraphViewCodec.js deleted file mode 100644 index 110b212..0000000 --- a/src/js/io/mxGraphViewCodec.js +++ /dev/null @@ -1,197 +0,0 @@ -/** - * $Id: mxGraphViewCodec.js,v 1.18 2010-12-03 11:05:52 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -mxCodecRegistry.register(function() -{ - /** - * Class: mxGraphViewCodec - * - * Custom encoder for s. This class is created - * and registered dynamically at load time and used implicitely via - * and the . This codec only writes views - * into a XML format that can be used to create an image for - * the graph, that is, it contains absolute coordinates with - * computed perimeters, edge styles and cell styles. - */ - var codec = new mxObjectCodec(new mxGraphView()); - - /** - * Function: encode - * - * Encodes the given using - * starting at the model's root. This returns the - * top-level graph node of the recursive encoding. - */ - codec.encode = function(enc, view) - { - return this.encodeCell(enc, view, - view.graph.getModel().getRoot()); - }; - - /** - * Function: encodeCell - * - * Recursively encodes the specifed cell. Uses layer - * as the default nodename. If the cell's parent is - * null, then graph is used for the nodename. If - * returns true for the cell, - * then edge is used for the nodename, else if - * returns true for the cell, - * then vertex is used for the nodename. - * - * is used to create the label - * attribute for the cell. For graph nodes and vertices - * the bounds are encoded into x, y, width and height. - * For edges the points are encoded into a points - * attribute as a space-separated list of comma-separated - * coordinate pairs (eg. x0,y0 x1,y1 ... xn,yn). All - * values from the cell style are added as attribute - * values to the node. - */ - codec.encodeCell = function(enc, view, cell) - { - var model = view.graph.getModel(); - var state = view.getState(cell); - var parent = model.getParent(cell); - - if (parent == null || state != null) - { - var childCount = model.getChildCount(cell); - var geo = view.graph.getCellGeometry(cell); - var name = null; - - if (parent == model.getRoot()) - { - name = 'layer'; - } - else if (parent == null) - { - name = 'graph'; - } - else if (model.isEdge(cell)) - { - name = 'edge'; - } - else if (childCount > 0 && geo != null) - { - name = 'group'; - } - else if (model.isVertex(cell)) - { - name = 'vertex'; - } - - if (name != null) - { - var node = enc.document.createElement(name); - var lab = view.graph.getLabel(cell); - - if (lab != null) - { - node.setAttribute('label', view.graph.getLabel(cell)); - - if (view.graph.isHtmlLabel(cell)) - { - node.setAttribute('html', true); - } - } - - if (parent == null) - { - var bounds = view.getGraphBounds(); - - if (bounds != null) - { - node.setAttribute('x', Math.round(bounds.x)); - node.setAttribute('y', Math.round(bounds.y)); - node.setAttribute('width', Math.round(bounds.width)); - node.setAttribute('height', Math.round(bounds.height)); - } - - node.setAttribute('scale', view.scale); - } - else if (state != null && geo != null) - { - // Writes each key, value in the style pair to an attribute - for (var i in state.style) - { - var value = state.style[i]; - - // Tries to turn objects and functions into strings - if (typeof(value) == 'function' && - typeof(value) == 'object') - { - value = mxStyleRegistry.getName(value); - } - - if (value != null && - typeof(value) != 'function' && - typeof(value) != 'object') - { - node.setAttribute(i, value); - } - } - - var abs = state.absolutePoints; - - // Writes the list of points into one attribute - if (abs != null && abs.length > 0) - { - var pts = Math.round(abs[0].x) + ',' + Math.round(abs[0].y); - - for (var i=1; is. This class is created and registered - * dynamically at load time and used implicitely via - * and the . - */ - var codec = new mxObjectCodec(new mxGraphModel()); - - /** - * Function: encodeObject - * - * Encodes the given by writing a (flat) XML sequence of - * cell nodes as produced by the . The sequence is - * wrapped-up in a node with the name root. - */ - codec.encodeObject = function(enc, obj, node) - { - var rootNode = enc.document.createElement('root'); - enc.encodeCell(obj.getRoot(), rootNode); - node.appendChild(rootNode); - }; - - /** - * Function: decodeChild - * - * Overrides decode child to handle special child nodes. - */ - codec.decodeChild = function(dec, child, obj) - { - if (child.nodeName == 'root') - { - this.decodeRoot(dec, child, obj); - } - else - { - mxObjectCodec.prototype.decodeChild.apply(this, arguments); - } - }; - - /** - * Function: decodeRoot - * - * Reads the cells into the graph model. All cells - * are children of the root element in the node. - */ - codec.decodeRoot = function(dec, root, model) - { - var rootCell = null; - var tmp = root.firstChild; - - while (tmp != null) - { - var cell = dec.decodeCell(tmp); - - if (cell != null && cell.getParent() == null) - { - rootCell = cell; - } - - tmp = tmp.nextSibling; - } - - // Sets the root on the model if one has been decoded - if (rootCell != null) - { - model.setRoot(rootCell); - } - }; - - // Returns the codec into the registry - return codec; - -}()); diff --git a/src/js/io/mxObjectCodec.js b/src/js/io/mxObjectCodec.js deleted file mode 100644 index 9d2473a..0000000 --- a/src/js/io/mxObjectCodec.js +++ /dev/null @@ -1,983 +0,0 @@ -/** - * $Id: mxObjectCodec.js,v 1.49 2010-12-01 09:19:58 gaudenz Exp $ - * Copyright (c) 2006-2010, JGraph Ltd - */ -/** - * Class: mxObjectCodec - * - * Generic codec for JavaScript objects that implements a mapping between - * JavaScript objects and XML nodes that maps each field or element to an - * attribute or child node, and vice versa. - * - * Atomic Values: - * - * Consider the following example. - * - * (code) - * var obj = new Object(); - * obj.foo = "Foo"; - * obj.bar = "Bar"; - * (end) - * - * This object is encoded into an XML node using the following. - * - * (code) - * var enc = new mxCodec(); - * var node = enc.encode(obj); - * (end) - * - * The output of the encoding may be viewed using as follows. - * - * (code) - * mxLog.show(); - * mxLog.debug(mxUtils.getPrettyXml(node)); - * (end) - * - * Finally, the result of the encoding looks as follows. - * - * (code) - * - * (end) - * - * In the above output, the foo and bar fields have been mapped to attributes - * with the same names, and the name of the constructor was used for the - * nodename. - * - * Booleans: - * - * Since booleans are numbers in JavaScript, all boolean values are encoded - * into 1 for true and 0 for false. The decoder also accepts the string true - * and false for boolean values. - * - * Objects: - * - * The above scheme is applied to all atomic fields, that is, to all non-object - * fields of an object. For object fields, a child node is created with a - * special attribute that contains the fieldname. This special attribute is - * called "as" and hence, as is a reserved word that should not be used for a - * fieldname. - * - * Consider the following example where foo is an object and bar is an atomic - * property of foo. - * - * (code) - * var obj = {foo: {bar: "Bar"}}; - * (end) - * - * This will be mapped to the following XML structure by mxObjectCodec. - * - * (code) - * - * - * - * (end) - * - * In the above output, the inner Object node contains the as-attribute that - * specifies the fieldname in the enclosing object. That is, the field foo was - * mapped to a child node with an as-attribute that has the value foo. - * - * Arrays: - * - * Arrays are special objects that are either associative, in which case each - * key, value pair is treated like a field where the key is the fieldname, or - * they are a sequence of atomic values and objects, which is mapped to a - * sequence of child nodes. For object elements, the above scheme is applied - * without the use of the special as-attribute for creating each child. For - * atomic elements, a special add-node is created with the value stored in the - * value-attribute. - * - * For example, the following array contains one atomic value and one object - * with a field called bar. Furthermore it contains two associative entries - * called bar with an atomic value, and foo with an object value. - * - * (code) - * var obj = ["Bar", {bar: "Bar"}]; - * obj["bar"] = "Bar"; - * obj["foo"] = {bar: "Bar"}; - * (end) - * - * This array is represented by the following XML nodes. - * - * (code) - * - * - * - * - * - * (end) - * - * The Array node name is the name of the constructor. The additional - * as-attribute in the last child contains the key of the associative entry, - * whereas the second last child is part of the array sequence and does not - * have an as-attribute. - * - * References: - * - * Objects may be represented as child nodes or attributes with ID values, - * which are used to lookup the object in a table within . The - * function is in charge of deciding if a specific field should - * be encoded as a reference or not. Its default implementation returns true if - * the fieldname is in , an array of strings that is used to configure - * the . - * - * Using this approach, the mapping does not guarantee that the referenced - * object itself exists in the document. The fields that are encoded as - * references must be carefully chosen to make sure all referenced objects - * exist in the document, or may be resolved by some other means if necessary. - * - * For example, in the case of the graph model all cells are stored in a tree - * whose root is referenced by the model's root field. A tree is a structure - * that is well suited for an XML representation, however, the additional edges - * in the graph model have a reference to a source and target cell, which are - * also contained in the tree. To handle this case, the source and target cell - * of an edge are treated as references, whereas the children are treated as - * objects. Since all cells are contained in the tree and no edge references a - * source or target outside the tree, this setup makes sure all referenced - * objects are contained in the document. - * - * In the case of a tree structure we must further avoid infinite recursion by - * ignoring the parent reference of each child. This is done by returning true - * in , whose default implementation uses the array of excluded - * fieldnames passed to the mxObjectCodec constructor. - * - * References are only used for cells in mxGraph. For defining other - * referencable object types, the codec must be able to work out the ID of an - * object. This is done by implementing . For decoding a - * reference, the XML node with the respective id-attribute is fetched from the - * document, decoded, and stored in a lookup table for later reference. For - * looking up external objects, may be implemented. - * - * Expressions: - * - * For decoding JavaScript expressions, the add-node may be used with a text - * content that contains the JavaScript expression. For example, the following - * creates a field called foo in the enclosing object and assigns it the value - * of . - * - * (code) - * - * mxConstants.ALIGN_LEFT - * - * (end) - * - * The resulting object has a field called foo with the value "left". Its XML - * representation looks as follows. - * - * (code) - * - * (end) - * - * This means the expression is evaluated at decoding time and the result of - * the evaluation is stored in the respective field. Valid expressions are all - * JavaScript expressions, including function definitions, which are mapped to - * functions on the resulting object. - * - * Constructor: mxObjectCodec - * - * Constructs a new codec for the specified template object. - * The variables in the optional exclude array are ignored by - * the codec. Variables in the optional idrefs array are - * turned into references in the XML. The optional mapping - * may be used to map from variable names to XML attributes. - * The argument is created as follows: - * - * (code) - * var mapping = new Object(); - * mapping['variableName'] = 'attribute-name'; - * (end) - * - * Parameters: - * - * template - Prototypical instance of the object to be - * encoded/decoded. - * exclude - Optional array of fieldnames to be ignored. - * idrefs - Optional array of fieldnames to be converted to/from - * references. - * mapping - Optional mapping from field- to attributenames. - */ -function mxObjectCodec(template, exclude, idrefs, mapping) -{ - this.template = template; - - this.exclude = (exclude != null) ? exclude : []; - this.idrefs = (idrefs != null) ? idrefs : []; - this.mapping = (mapping != null) ? mapping : []; - - this.reverse = new Object(); - - for (var i in this.mapping) - { - this.reverse[this.mapping[i]] = i; - } -}; - -/** - * Variable: template - * - * Holds the template object associated with this codec. - */ -mxObjectCodec.prototype.template = null; - -/** - * Variable: exclude - * - * Array containing the variable names that should be - * ignored by the codec. - */ -mxObjectCodec.prototype.exclude = null; - -/** - * Variable: idrefs - * - * Array containing the variable names that should be - * turned into or converted from references. See - * and . - */ -mxObjectCodec.prototype.idrefs = null; - -/** - * Variable: mapping - * - * Maps from from fieldnames to XML attribute names. - */ -mxObjectCodec.prototype.mapping = null; - -/** - * Variable: reverse - * - * Maps from from XML attribute names to fieldnames. - */ -mxObjectCodec.prototype.reverse = null; - -/** - * Function: getName - * - * Returns the name used for the nodenames and lookup of the codec when - * classes are encoded and nodes are decoded. For classes to work with - * this the codec registry automatically adds an alias for the classname - * if that is different than what this returns. The default implementation - * returns the classname of the template class. - */ -mxObjectCodec.prototype.getName = function() -{ - return mxUtils.getFunctionName(this.template.constructor); -}; - -/** - * Function: cloneTemplate - * - * Returns a new instance of the template for this codec. - */ -mxObjectCodec.prototype.cloneTemplate = function() -{ - return new this.template.constructor(); -}; - -/** - * Function: getFieldName - * - * Returns the fieldname for the given attributename. - * Looks up the value in the mapping or returns - * the input if there is no reverse mapping for the - * given name. - */ -mxObjectCodec.prototype.getFieldName = function(attributename) -{ - if (attributename != null) - { - var mapped = this.reverse[attributename]; - - if (mapped != null) - { - attributename = mapped; - } - } - - return attributename; -}; - -/** - * Function: getAttributeName - * - * Returns the attributename for the given fieldname. - * Looks up the value in the or returns - * the input if there is no mapping for the - * given name. - */ -mxObjectCodec.prototype.getAttributeName = function(fieldname) -{ - if (fieldname != null) - { - var mapped = this.mapping[fieldname]; - - if (mapped != null) - { - fieldname = mapped; - } - } - - return fieldname; -}; - -/** - * Function: isExcluded - * - * Returns true if the given attribute is to be ignored by the codec. This - * implementation returns true if the given fieldname is in or - * if the fieldname equals . - * - * Parameters: - * - * obj - Object instance that contains the field. - * attr - Fieldname of the field. - * value - Value of the field. - * write - Boolean indicating if the field is being encoded or decoded. - * Write is true if the field is being encoded, else it is being decoded. - */ -mxObjectCodec.prototype.isExcluded = function(obj, attr, value, write) -{ - return attr == mxObjectIdentity.FIELD_NAME || - mxUtils.indexOf(this.exclude, attr) >= 0; -}; - -/** - * Function: isReference - * - * Returns true if the given fieldname is to be treated - * as a textual reference (ID). This implementation returns - * true if the given fieldname is in . - * - * Parameters: - * - * obj - Object instance that contains the field. - * attr - Fieldname of the field. - * value - Value of the field. - * write - Boolean indicating if the field is being encoded or decoded. - * Write is true if the field is being encoded, else it is being decoded. - */ -mxObjectCodec.prototype.isReference = function(obj, attr, value, write) -{ - return mxUtils.indexOf(this.idrefs, attr) >= 0; -}; - -/** - * Function: encode - * - * Encodes the specified object and returns a node - * representing then given object. Calls - * after creating the node and with the - * resulting node after processing. - * - * Enc is a reference to the calling encoder. It is used - * to encode complex objects and create references. - * - * This implementation encodes all variables of an - * object according to the following rules: - * - * - If the variable name is in then it is ignored. - * - If the variable name is in then - * is used to replace the object with its ID. - * - The variable name is mapped using . - * - If obj is an array and the variable name is numeric - * (ie. an index) then it is not encoded. - * - If the value is an object, then the codec is used to - * create a child node with the variable name encoded into - * the "as" attribute. - * - Else, if is true or the value differs - * from the template value, then ... - * - ... if obj is not an array, then the value is mapped to - * an attribute. - * - ... else if obj is an array, the value is mapped to an - * add child with a value attribute or a text child node, - * if the value is a function. - * - * If no ID exists for a variable in or if an object - * cannot be encoded, a warning is issued using . - * - * Returns the resulting XML node that represents the given - * object. - * - * Parameters: - * - * enc - that controls the encoding process. - * obj - Object to be encoded. - */ -mxObjectCodec.prototype.encode = function(enc, obj) -{ - var node = enc.document.createElement(this.getName()); - - obj = this.beforeEncode(enc, obj, node); - this.encodeObject(enc, obj, node); - - return this.afterEncode(enc, obj, node); -}; - -/** - * Function: encodeObject - * - * Encodes the value of each member in then given obj into the given node using - * . - * - * Parameters: - * - * enc - that controls the encoding process. - * obj - Object to be encoded. - * node - XML node that contains the encoded object. - */ -mxObjectCodec.prototype.encodeObject = function(enc, obj, node) -{ - enc.setAttribute(node, 'id', enc.getId(obj)); - - for (var i in obj) - { - var name = i; - var value = obj[name]; - - if (value != null && !this.isExcluded(obj, name, value, true)) - { - if (mxUtils.isNumeric(name)) - { - name = null; - } - - this.encodeValue(enc, obj, name, value, node); - } - } -}; - -/** - * Function: encodeValue - * - * Converts the given value according to the mappings - * and id-refs in this codec and uses - * to write the attribute into the given node. - * - * Parameters: - * - * enc - that controls the encoding process. - * obj - Object whose property is going to be encoded. - * name - XML node that contains the encoded object. - * value - Value of the property to be encoded. - * node - XML node that contains the encoded object. - */ -mxObjectCodec.prototype.encodeValue = function(enc, obj, - name, value, node) -{ - if (value != null) - { - if (this.isReference(obj, name, value, true)) - { - var tmp = enc.getId(value); - - if (tmp == null) - { - mxLog.warn('mxObjectCodec.encode: No ID for ' + - this.getName() + '.' + name + '=' + value); - return; // exit - } - - value = tmp; - } - - var defaultValue = this.template[name]; - - // Checks if the value is a default value and - // the name is correct - if (name == null || enc.encodeDefaults || - defaultValue != value) - { - name = this.getAttributeName(name); - this.writeAttribute(enc, obj, name, value, node); - } - } -}; - -/** - * Function: writeAttribute - * - * Writes the given value into node using - * or depending on the type of the value. - */ -mxObjectCodec.prototype.writeAttribute = function(enc, obj, - attr, value, node) -{ - if (typeof(value) != 'object' /* primitive type */) - { - this.writePrimitiveAttribute(enc, obj, attr, value, node); - } - else /* complex type */ - { - this.writeComplexAttribute(enc, obj, attr, value, node); - } -}; - -/** - * Function: writePrimitiveAttribute - * - * Writes the given value as an attribute of the given node. - */ -mxObjectCodec.prototype.writePrimitiveAttribute = function(enc, obj, - attr, value, node) -{ - value = this.convertValueToXml(value); - - if (attr == null) - { - var child = enc.document.createElement('add'); - - if (typeof(value) == 'function') - { - child.appendChild( - enc.document.createTextNode(value)); - } - else - { - enc.setAttribute(child, 'value', value); - } - - node.appendChild(child); - } - else if (typeof(value) != 'function') - { - enc.setAttribute(node, attr, value); - } -}; - -/** - * Function: writeComplexAttribute - * - * Writes the given value as a child node of the given node. - */ -mxObjectCodec.prototype.writeComplexAttribute = function(enc, obj, - attr, value, node) -{ - var child = enc.encode(value); - - if (child != null) - { - if (attr != null) - { - child.setAttribute('as', attr); - } - - node.appendChild(child); - } - else - { - mxLog.warn('mxObjectCodec.encode: No node for ' + - this.getName() + '.' + attr + ': ' + value); - } -}; - -/** - * Function: convertValueToXml - * - * Converts true to "1" and false to "0". All other values are ignored. - */ -mxObjectCodec.prototype.convertValueToXml = function(value) -{ - // Makes sure to encode boolean values as numeric values - if (typeof(value.length) == 'undefined' && - (value == true || - value == false)) - { - // Checks if the value is true (do not use the - // value as is, because this would check if the - // value is not null, so 0 would be true! - value = (value == true) ? '1' : '0'; - } - return value; -}; - -/** - * Function: convertValueFromXml - * - * Converts booleans and numeric values to the respective types. - */ -mxObjectCodec.prototype.convertValueFromXml = function(value) -{ - if (mxUtils.isNumeric(value)) - { - value = parseFloat(value); - } - - return value; -}; - -/** - * Function: beforeEncode - * - * Hook for subclassers to pre-process the object before - * encoding. This returns the input object. The return - * value of this function is used in to perform - * the default encoding into the given node. - * - * Parameters: - * - * enc - that controls the encoding process. - * obj - Object to be encoded. - * node - XML node to encode the object into. - */ -mxObjectCodec.prototype.beforeEncode = function(enc, obj, node) -{ - return obj; -}; - -/** - * Function: afterEncode - * - * Hook for subclassers to post-process the node - * for the given object after encoding and return the - * post-processed node. This implementation returns - * the input node. The return value of this method - * is returned to the encoder from . - * - * Parameters: - * - * enc - that controls the encoding process. - * obj - Object to be encoded. - * node - XML node that represents the default encoding. - */ -mxObjectCodec.prototype.afterEncode = function(enc, obj, node) -{ - return node; -}; - -/** - * Function: decode - * - * Parses the given node into the object or returns a new object - * representing the given node. - * - * Dec is a reference to the calling decoder. It is used to decode - * complex objects and resolve references. - * - * If a node has an id attribute then the object cache is checked for the - * object. If the object is not yet in the cache then it is constructed - * using the constructor of