From 9457ca6047afc3035b412c4c14aa6887c1e95b52 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Mon, 4 Oct 2021 17:05:34 -0700 Subject: [PATCH] Enable eslit for mindplot --- packages/mindplot/.eslintrc.json | 11 + .../lib/components/ActionDispatcher.js | 132 +- .../mindplot/lib/components/ActionIcon.js | 66 +- .../mindplot/lib/components/CentralTopic.js | 85 +- packages/mindplot/lib/components/Command.js | 52 +- .../mindplot/lib/components/ConnectionLine.js | 292 +- .../mindplot/lib/components/ControlPoint.js | 351 +- packages/mindplot/lib/components/Designer.js | 1492 +- .../lib/components/DesignerActionRunner.js | 56 +- .../lib/components/DesignerKeyboard.js | 763 +- .../mindplot/lib/components/DesignerModel.js | 230 +- .../lib/components/DesignerUndoManager.js | 122 +- .../mindplot/lib/components/DragConnector.js | 167 +- .../mindplot/lib/components/DragManager.js | 297 +- packages/mindplot/lib/components/DragPivot.js | 478 +- packages/mindplot/lib/components/DragTopic.js | 367 +- .../mindplot/lib/components/EditorOptions.js | 9 +- .../lib/components/EditorProperties.js | 76 +- packages/mindplot/lib/components/Events.js | 70 +- packages/mindplot/lib/components/Icon.js | 59 +- packages/mindplot/lib/components/IconGroup.js | 494 +- packages/mindplot/lib/components/ImageIcon.js | 264 +- packages/mindplot/lib/components/Keyboard.js | 18 +- packages/mindplot/lib/components/LinkIcon.js | 82 +- .../lib/components/LocalStorageManager.js | 79 +- packages/mindplot/lib/components/MainTopic.js | 339 +- packages/mindplot/lib/components/Messages.js | 32 +- .../lib/components/MultilineTextEditor.js | 547 +- packages/mindplot/lib/components/NodeGraph.js | 276 +- packages/mindplot/lib/components/NoteIcon.js | 108 +- packages/mindplot/lib/components/Options.js | 18 +- .../lib/components/PersistenceManager.js | 87 +- .../mindplot/lib/components/Relationship.js | 604 +- .../lib/components/RelationshipPivot.js | 258 +- .../lib/components/RestPersistenceManager.js | 269 +- .../mindplot/lib/components/ScreenManager.js | 243 +- .../lib/components/ShrinkConnector.js | 157 +- .../components/StandaloneActionDispatcher.js | 554 +- .../mindplot/lib/components/TextEditor.js | 530 +- .../lib/components/TextEditorFactory.js | 14 +- packages/mindplot/lib/components/Topic.js | 2454 ++- .../lib/components/TopicEventDispatcher.js | 94 +- .../mindplot/lib/components/TopicFeature.js | 78 +- .../mindplot/lib/components/TopicStyle.js | 194 +- packages/mindplot/lib/components/Workspace.js | 455 +- .../commands/AddFeatureToTopicCommand.js | 65 +- .../commands/AddRelationshipCommand.js | 44 +- .../components/commands/AddTopicCommand.js | 106 +- .../commands/ChangeFeatureToTopicCommand.js | 48 +- .../lib/components/commands/DeleteCommand.js | 279 +- .../components/commands/DragTopicCommand.js | 130 +- .../commands/GenericFunctionCommand.js | 124 +- .../commands/MoveControlPointCommand.js | 155 +- .../commands/RemoveFeatureFromTopicCommand.js | 58 +- .../mindplot/lib/components/commands/index.js | 18 +- packages/mindplot/lib/components/footer.js | 4 +- packages/mindplot/lib/components/header.js | 4 +- packages/mindplot/lib/components/index.js | 92 +- .../components/layout/AbstractBasicSorter.js | 88 +- .../lib/components/layout/BalancedSorter.js | 464 +- .../lib/components/layout/ChangeEvent.js | 70 +- .../layout/ChildrenSorterStrategy.js | 72 +- .../lib/components/layout/EventBus.js | 24 +- .../components/layout/EventBusDispatcher.js | 123 +- .../lib/components/layout/GridSorter.js | 75 +- .../lib/components/layout/LayoutManager.js | 314 +- .../mindplot/lib/components/layout/Node.js | 369 +- .../lib/components/layout/OriginalLayout.js | 452 +- .../lib/components/layout/RootedTreeSet.js | 628 +- .../lib/components/layout/SymmetricSorter.js | 469 +- .../mindplot/lib/components/layout/index.js | 24 +- .../bootstrap/BootstrapDialog.Request.js | 81 +- .../libraries/bootstrap/BootstrapDialog.js | 212 +- .../bootstrap/js/bootstrap-colorpicker.js | 1842 +- .../bootstrap/js/bootstrap-colorpicker.min.js | 104 +- .../libraries/bootstrap/js/bootstrap.js | 1903 +- .../libraries/bootstrap/js/bootstrap.min.js | 35 +- .../libraries/hotkeys/jquery.hotkeys.js | 220 +- .../libraries/jquery/jquery-2.1.0.js | 16712 ++++++++-------- .../libraries/jquery/jquery-2.1.0.min.js | 187 +- .../libraries/jquery/jquery.mousewheel.min.js | 6 +- .../libraries/less/less-1.4.2.min.js | 366 +- .../libraries/less/less-1.6.2.min.js | 427 +- .../mootools-core-1.4.5-full-nocompat-yc.js | 1086 +- .../libraries/mootools/mootools-core-1.4.5.js | 311 +- .../libraries/mootools/mootools-core-1.6.0.js | 10367 +++++----- .../libraries/underscorejs/underscore-min.js | 10 +- .../lib/components/model/FeatureModel.js | 112 +- .../mindplot/lib/components/model/IMindmap.js | 238 +- .../lib/components/model/INodeModel.js | 577 +- .../lib/components/model/IconModel.js | 34 +- .../lib/components/model/LinkModel.js | 69 +- .../mindplot/lib/components/model/Mindmap.js | 217 +- .../lib/components/model/NodeModel.js | 311 +- .../lib/components/model/NoteModel.js | 36 +- .../lib/components/model/RelationshipModel.js | 196 +- .../mindplot/lib/components/model/index.js | 18 +- .../persistence/Beta2PelaMigrator.js | 62 +- .../components/persistence/ModelCodeName.js | 8 +- .../persistence/Pela2TangoMigrator.js | 137 +- .../persistence/XMLSerializerFactory.js | 89 +- .../persistence/XMLSerializer_Beta.js | 517 +- .../persistence/XMLSerializer_Pela.js | 843 +- .../persistence/XMLSerializer_Tango.js | 6 +- .../lib/components/persistence/index.js | 14 +- .../lib/components/util/FadeEffect.js | 36 +- .../mindplot/lib/components/util/Shape.js | 202 +- .../mindplot/lib/components/util/index.js | 4 +- .../components/widget/ColorPalettePanel.js | 140 +- .../lib/components/widget/FloatingTip.js | 78 +- .../lib/components/widget/FontFamilyPanel.js | 30 +- .../lib/components/widget/FontSizePanel.js | 28 +- .../mindplot/lib/components/widget/IMenu.js | 160 +- .../lib/components/widget/IconPanel.js | 83 +- .../widget/KeyboardShortcutTooltip.js | 80 +- .../lib/components/widget/LinkEditor.js | 206 +- .../lib/components/widget/LinkIconTooltip.js | 96 +- .../lib/components/widget/ListToolbarPanel.js | 56 +- .../mindplot/lib/components/widget/Menu.js | 916 +- .../components/widget/ModalDialogNotifier.js | 52 +- .../lib/components/widget/NoteEditor.js | 127 +- .../lib/components/widget/ToolbarItem.js | 98 +- .../lib/components/widget/ToolbarNotifier.js | 44 +- .../lib/components/widget/ToolbarPaneItem.js | 170 +- .../lib/components/widget/TopicShapePanel.js | 28 +- .../mindplot/lib/components/widget/index.js | 34 +- packages/mindplot/lib/mindplot.js | 73 +- packages/mindplot/package.json | 10 + packages/mindplot/webpack.common.js | 10 +- packages/web2d/.eslintrc.json | 2 +- packages/web2d/webpack.common.js | 40 +- 131 files changed, 29396 insertions(+), 28482 deletions(-) create mode 100644 packages/mindplot/.eslintrc.json diff --git a/packages/mindplot/.eslintrc.json b/packages/mindplot/.eslintrc.json new file mode 100644 index 00000000..ca9bff03 --- /dev/null +++ b/packages/mindplot/.eslintrc.json @@ -0,0 +1,11 @@ +{ + "env": { + "browser": true, + "commonjs": true + }, + "extends": [ + "airbnb-base" + ], + "plugins": ["only-warn"], + "rules": {} +} \ No newline at end of file diff --git a/packages/mindplot/lib/components/ActionDispatcher.js b/packages/mindplot/lib/components/ActionDispatcher.js index 880f1391..fc3fd102 100644 --- a/packages/mindplot/lib/components/ActionDispatcher.js +++ b/packages/mindplot/lib/components/ActionDispatcher.js @@ -17,96 +17,96 @@ */ const Events = require('./Events').default; -//noinspection JSUnusedLocalSymbols +// noinspection JSUnusedLocalSymbols const ActionDispatcher = new Class({ - Implements:[Events], - initialize: function(commandContext) { - $assert(commandContext, "commandContext can not be null"); - }, + Implements: [Events], + initialize(commandContext) { + $assert(commandContext, 'commandContext can not be null'); + }, - addRelationship: function(model, mindmap) { - throw "method must be implemented."; - }, + addRelationship(model, mindmap) { + throw 'method must be implemented.'; + }, - addTopics: function(models, parentTopicId) { - throw "method must be implemented."; - }, + addTopics(models, parentTopicId) { + throw 'method must be implemented.'; + }, - deleteEntities: function(topicsIds, relIds) { - throw "method must be implemented."; - }, + deleteEntities(topicsIds, relIds) { + throw 'method must be implemented.'; + }, - dragTopic: function(topicId, position, order, parentTopic) { - throw "method must be implemented."; - }, + dragTopic(topicId, position, order, parentTopic) { + throw 'method must be implemented.'; + }, - moveTopic: function(topicId, position) { - throw "method must be implemented."; - }, + moveTopic(topicId, position) { + throw 'method must be implemented.'; + }, - moveControlPoint: function(ctrlPoint, point) { - throw "method must be implemented."; - }, + moveControlPoint(ctrlPoint, point) { + throw 'method must be implemented.'; + }, - changeFontFamilyToTopic: function(topicIds, fontFamily) { - throw "method must be implemented."; - }, + changeFontFamilyToTopic(topicIds, fontFamily) { + throw 'method must be implemented.'; + }, - changeFontStyleToTopic: function(topicsIds) { - throw "method must be implemented."; - }, + changeFontStyleToTopic(topicsIds) { + throw 'method must be implemented.'; + }, - changeFontColorToTopic: function(topicsIds, color) { - throw "method must be implemented."; - }, + changeFontColorToTopic(topicsIds, color) { + throw 'method must be implemented.'; + }, - changeFontSizeToTopic : function(topicsIds, size) { - throw "method must be implemented."; - }, + changeFontSizeToTopic(topicsIds, size) { + throw 'method must be implemented.'; + }, - changeBackgroundColorToTopic: function(topicsIds, color) { - throw "method must be implemented."; - }, + changeBackgroundColorToTopic(topicsIds, color) { + throw 'method must be implemented.'; + }, - changeBorderColorToTopic: function(topicsIds, color) { - throw "method must be implemented."; - }, + changeBorderColorToTopic(topicsIds, color) { + throw 'method must be implemented.'; + }, - changeShapeTypeToTopic : function(topicsIds, shapeType) { - throw "method must be implemented."; - }, + changeShapeTypeToTopic(topicsIds, shapeType) { + throw 'method must be implemented.'; + }, - changeFontWeightToTopic : function(topicsIds) { - throw "method must be implemented."; - }, + changeFontWeightToTopic(topicsIds) { + throw 'method must be implemented.'; + }, - changeTextToTopic : function(topicsIds, text) { - throw "method must be implemented."; - }, + changeTextToTopic(topicsIds, text) { + throw 'method must be implemented.'; + }, - shrinkBranch : function(topicsIds, collapse) { - throw "method must be implemented."; - }, + shrinkBranch(topicsIds, collapse) { + throw 'method must be implemented.'; + }, - addFeatureToTopic : function(topicId, type, attributes) { - throw "method must be implemented."; - }, + addFeatureToTopic(topicId, type, attributes) { + throw 'method must be implemented.'; + }, - changeFeatureToTopic : function(topicId, featureId, attributes) { - throw "method must be implemented."; - }, + changeFeatureToTopic(topicId, featureId, attributes) { + throw 'method must be implemented.'; + }, - removeFeatureFromTopic : function(topicId, featureId) { - throw "method must be implemented."; - } + removeFeatureFromTopic(topicId, featureId) { + throw 'method must be implemented.'; + }, }); -ActionDispatcher.setInstance = function(dispatcher) { - ActionDispatcher._instance = dispatcher; +ActionDispatcher.setInstance = function (dispatcher) { + ActionDispatcher._instance = dispatcher; }; -ActionDispatcher.getInstance = function() { - return ActionDispatcher._instance; +ActionDispatcher.getInstance = function () { + return ActionDispatcher._instance; }; export default ActionDispatcher; diff --git a/packages/mindplot/lib/components/ActionIcon.js b/packages/mindplot/lib/components/ActionIcon.js index 094cd328..96ed6df7 100644 --- a/packages/mindplot/lib/components/ActionIcon.js +++ b/packages/mindplot/lib/components/ActionIcon.js @@ -18,47 +18,47 @@ const Icon = require('./Icon').default; const ActionIcon = new Class({ - Extends:Icon, - initialize: function(topic, url) { - this.parent(url); - this._node = topic; - }, - getNode:function() { - return this._node; - }, + Extends: Icon, + initialize(topic, url) { + this.parent(url); + this._node = topic; + }, + getNode() { + return this._node; + }, - setPosition:function(x, y) { - var size = this.getSize(); - this.getImage().setPosition(x - size.width / 2, y - size.height / 2); - }, + setPosition(x, y) { + const size = this.getSize(); + this.getImage().setPosition(x - size.width / 2, y - size.height / 2); + }, - addEvent:function(event, fn) { - this.getImage().addEvent(event, fn); - }, + addEvent(event, fn) { + this.getImage().addEvent(event, fn); + }, - addToGroup:function(group) { - group.append(this.getImage()); - }, + addToGroup(group) { + group.append(this.getImage()); + }, - setVisibility:function(visible) { - this.getImage().setVisibility(visible); - }, + setVisibility(visible) { + this.getImage().setVisibility(visible); + }, - isVisible:function() { - return this.getImage().isVisible(); - }, + isVisible() { + return this.getImage().isVisible(); + }, - setCursor:function(cursor) { - return this.getImage().setCursor(cursor); - }, + setCursor(cursor) { + return this.getImage().setCursor(cursor); + }, - moveToBack:function(cursor) { - return this.getImage().moveToBack(cursor); - }, + moveToBack(cursor) { + return this.getImage().moveToBack(cursor); + }, - moveToFront:function(cursor) { - return this.getImage().moveToFront(cursor); - } + moveToFront(cursor) { + return this.getImage().moveToFront(cursor); + }, }); export default ActionIcon; diff --git a/packages/mindplot/lib/components/CentralTopic.js b/packages/mindplot/lib/components/CentralTopic.js index 260f5dd6..d94ad143 100644 --- a/packages/mindplot/lib/components/CentralTopic.js +++ b/packages/mindplot/lib/components/CentralTopic.js @@ -16,66 +16,67 @@ * limitations under the License. */ const Core = require('@wismapping/core-js'); + const core = Core(); const Topic = require('./Topic').default; const Shape = require('./util/Shape').default; const CentralTopic = new Class( - /** @lends CentralTopic*/ { - Extends: Topic, - /** + /** @lends CentralTopic */ { + Extends: Topic, + /** * @extends mindplot.Topic * @constructs * @param model * @param options */ - initialize: function (model, options) { - this.parent(model, options); - }, + initialize(model, options) { + this.parent(model, options); + }, - _registerEvents: function () { - this.parent(); + _registerEvents() { + this.parent(); - // This disable the drag of the central topic. But solves the problem of deselecting the nodes when the screen is clicked. - this.addEvent('mousedown', function (event) { - event.stopPropagation(); - }); - }, + // This disable the drag of the central topic. But solves the problem of deselecting the nodes when the screen is clicked. + this.addEvent('mousedown', (event) => { + event.stopPropagation(); + }); + }, - /** */ - workoutIncomingConnectionPoint: function () { - return this.getPosition(); - }, + /** */ + workoutIncomingConnectionPoint() { + return this.getPosition(); + }, - /** */ - setCursor: function (type) { - type = type == 'move' ? 'default' : type; - this.parent(type); - }, + /** */ + setCursor(type) { + type = type == 'move' ? 'default' : type; + this.parent(type); + }, - /** */ - updateTopicShape: function () {}, + /** */ + updateTopicShape() {}, - _updatePositionOnChangeSize: function () { - // Center main topic ... - var zeroPoint = new core.Point(0, 0); - this.setPosition(zeroPoint); - }, + _updatePositionOnChangeSize() { + // Center main topic ... + const zeroPoint = new core.Point(0, 0); + this.setPosition(zeroPoint); + }, - /** */ - getShrinkConnector: function () { - return null; - }, + /** */ + getShrinkConnector() { + return null; + }, - /** */ - workoutOutgoingConnectionPoint: function (targetPosition) { - $assert(targetPosition, 'targetPoint can not be null'); - var pos = this.getPosition(); - var isAtRight = Shape.isAtRight(targetPosition, pos); - var size = this.getSize(); - return Shape.calculateRectConnectionPoint(pos, size, !isAtRight); - }, - } + /** */ + workoutOutgoingConnectionPoint(targetPosition) { + $assert(targetPosition, 'targetPoint can not be null'); + const pos = this.getPosition(); + const isAtRight = Shape.isAtRight(targetPosition, pos); + const size = this.getSize(); + return Shape.calculateRectConnectionPoint(pos, size, !isAtRight); + }, + }, ); export default CentralTopic; diff --git a/packages/mindplot/lib/components/Command.js b/packages/mindplot/lib/components/Command.js index 91ed9ec2..87d4d4ea 100644 --- a/packages/mindplot/lib/components/Command.js +++ b/packages/mindplot/lib/components/Command.js @@ -17,51 +17,45 @@ */ const Command = new Class(/** @lends mindplot.Command */{ - /** + /** * @classdesc The command base class for handling do/undo mindmap operations * @constructs */ - initialize: function() - { - this._id = Command._nextUUID(); - }, + initialize() { + this._id = Command._nextUUID(); + }, - /** + /** * @abstract */ - execute: function(commandContext) - { - throw "execute must be implemented."; - }, + execute(commandContext) { + throw 'execute must be implemented.'; + }, - /** - * Triggered by the undo button - reverses the executed command + /** + * Triggered by the undo button - reverses the executed command * @abstract */ - undoExecute: function(commandContext) - { - throw "undo must be implemented."; - }, + undoExecute(commandContext) { + throw 'undo must be implemented.'; + }, - /** + /** * Returns the unique id of this command * @returns {Number} command id */ - getId:function() - { - return this._id; - } + getId() { + return this._id; + }, }); -Command._nextUUID = function() -{ - if (!$defined(Command._uuid)) - { - Command._uuid = 1; - } +Command._nextUUID = function () { + if (!$defined(Command._uuid)) { + Command._uuid = 1; + } - Command._uuid = Command._uuid + 1; - return Command._uuid; + Command._uuid += 1; + return Command._uuid; }; export default Command; diff --git a/packages/mindplot/lib/components/ConnectionLine.js b/packages/mindplot/lib/components/ConnectionLine.js index 1e3c8cc0..e5a78b54 100644 --- a/packages/mindplot/lib/components/ConnectionLine.js +++ b/packages/mindplot/lib/components/ConnectionLine.js @@ -16,8 +16,10 @@ * limitations under the License. */ const Core = require('@wismapping/core-js'); + const core = Core(); const web2D = require('@wismapping/web2d'); + const web2d = web2D(); const INodeModel = require('./model/INodeModel').default; @@ -25,182 +27,184 @@ const { TopicShape } = require('./model/INodeModel'); const Topic = require('./Topic').default; const ConnectionLine = new Class({ - initialize: function (sourceNode, targetNode, lineType) { - $assert(targetNode, 'parentNode node can not be null'); - $assert(sourceNode, 'childNode node can not be null'); - $assert(sourceNode != targetNode, 'Circular connection'); + initialize(sourceNode, targetNode, lineType) { + $assert(targetNode, 'parentNode node can not be null'); + $assert(sourceNode, 'childNode node can not be null'); + $assert(sourceNode != targetNode, 'Circular connection'); - this._targetTopic = targetNode; - this._sourceTopic = sourceNode; + this._targetTopic = targetNode; + this._sourceTopic = sourceNode; - var line; - var ctrlPoints = this._getCtrlPoints(sourceNode, targetNode); - if (targetNode.getType() == INodeModel.CENTRAL_TOPIC_TYPE) { - line = this._createLine(lineType, ConnectionLine.CURVED); - line.setSrcControlPoint(ctrlPoints[0]); - line.setDestControlPoint(ctrlPoints[1]); - } else { - line = this._createLine(lineType, ConnectionLine.SIMPLE_CURVED); - line.setSrcControlPoint(ctrlPoints[0]); - line.setDestControlPoint(ctrlPoints[1]); - } - // Set line styles ... - var strokeColor = ConnectionLine.getStrokeColor(); - line.setStroke(1, 'solid', strokeColor, 1); - line.setFill(strokeColor, 1); + let line; + const ctrlPoints = this._getCtrlPoints(sourceNode, targetNode); + if (targetNode.getType() == INodeModel.CENTRAL_TOPIC_TYPE) { + line = this._createLine(lineType, ConnectionLine.CURVED); + line.setSrcControlPoint(ctrlPoints[0]); + line.setDestControlPoint(ctrlPoints[1]); + } else { + line = this._createLine(lineType, ConnectionLine.SIMPLE_CURVED); + line.setSrcControlPoint(ctrlPoints[0]); + line.setDestControlPoint(ctrlPoints[1]); + } + // Set line styles ... + const strokeColor = ConnectionLine.getStrokeColor(); + line.setStroke(1, 'solid', strokeColor, 1); + line.setFill(strokeColor, 1); - this._line2d = line; - }, + this._line2d = line; + }, - _getCtrlPoints: function (sourceNode, targetNode) { - var srcPos = sourceNode.workoutOutgoingConnectionPoint(targetNode.getPosition()); - var destPos = targetNode.workoutIncomingConnectionPoint(sourceNode.getPosition()); - var deltaX = (srcPos.x - destPos.x) / 3; - return [new core.Point(deltaX, 0), new core.Point(-deltaX, 0)]; - }, + _getCtrlPoints(sourceNode, targetNode) { + const srcPos = sourceNode.workoutOutgoingConnectionPoint(targetNode.getPosition()); + const destPos = targetNode.workoutIncomingConnectionPoint(sourceNode.getPosition()); + const deltaX = (srcPos.x - destPos.x) / 3; + return [new core.Point(deltaX, 0), new core.Point(-deltaX, 0)]; + }, - _createLine: function (lineType, defaultStyle) { - if (!$defined(lineType)) { - lineType = defaultStyle; - } - lineType = parseInt(lineType); - this._lineType = lineType; - var line = null; - switch (lineType) { - case ConnectionLine.POLYLINE: - line = new web2d.PolyLine(); - break; - case ConnectionLine.CURVED: - line = new web2d.CurvedLine(); - break; - case ConnectionLine.SIMPLE_CURVED: - line = new web2d.CurvedLine(); - line.setStyle(web2d.CurvedLine.SIMPLE_LINE); - break; - default: - line = new web2d.Line(); - break; - } - return line; - }, + _createLine(lineType, defaultStyle) { + if (!$defined(lineType)) { + lineType = defaultStyle; + } + lineType = parseInt(lineType); + this._lineType = lineType; + let line = null; + switch (lineType) { + case ConnectionLine.POLYLINE: + line = new web2d.PolyLine(); + break; + case ConnectionLine.CURVED: + line = new web2d.CurvedLine(); + break; + case ConnectionLine.SIMPLE_CURVED: + line = new web2d.CurvedLine(); + line.setStyle(web2d.CurvedLine.SIMPLE_LINE); + break; + default: + line = new web2d.Line(); + break; + } + return line; + }, - setVisibility: function (value) { - this._line2d.setVisibility(value); - }, + setVisibility(value) { + this._line2d.setVisibility(value); + }, - isVisible: function () { - return this._line2d.isVisible(); - }, + isVisible() { + return this._line2d.isVisible(); + }, - setOpacity: function (opacity) { - this._line2d.setOpacity(opacity); - }, + setOpacity(opacity) { + this._line2d.setOpacity(opacity); + }, - redraw: function () { - var line2d = this._line2d; - var sourceTopic = this._sourceTopic; - var sourcePosition = sourceTopic.getPosition(); + redraw() { + const line2d = this._line2d; + const sourceTopic = this._sourceTopic; + const sourcePosition = sourceTopic.getPosition(); - var targetTopic = this._targetTopic; - var targetPosition = targetTopic.getPosition(); + const targetTopic = this._targetTopic; + const targetPosition = targetTopic.getPosition(); - var sPos, tPos; - sPos = sourceTopic.workoutOutgoingConnectionPoint(targetPosition); - tPos = targetTopic.workoutIncomingConnectionPoint(sourcePosition); + let sPos; let + tPos; + sPos = sourceTopic.workoutOutgoingConnectionPoint(targetPosition); + tPos = targetTopic.workoutIncomingConnectionPoint(sourcePosition); - line2d.setFrom(tPos.x, tPos.y); - line2d.setTo(sPos.x, sPos.y); + line2d.setFrom(tPos.x, tPos.y); + line2d.setTo(sPos.x, sPos.y); - if (line2d.getType() == 'CurvedLine') { - var ctrlPoints = this._getCtrlPoints(this._sourceTopic, this._targetTopic); - line2d.setSrcControlPoint(ctrlPoints[0]); - line2d.setDestControlPoint(ctrlPoints[1]); - } + if (line2d.getType() == 'CurvedLine') { + const ctrlPoints = this._getCtrlPoints(this._sourceTopic, this._targetTopic); + line2d.setSrcControlPoint(ctrlPoints[0]); + line2d.setDestControlPoint(ctrlPoints[1]); + } - // Add connector ... - this._positionateConnector(targetTopic); - }, + // Add connector ... + this._positionateConnector(targetTopic); + }, - _positionateConnector: function (targetTopic) { - var targetPosition = targetTopic.getPosition(); - var offset = Topic.CONNECTOR_WIDTH / 2; - var targetTopicSize = targetTopic.getSize(); - var y, x; - if (targetTopic.getShapeType() == TopicShape.LINE) { - y = targetTopicSize.height; - } else { - y = targetTopicSize.height / 2; - } - y = y - offset; + _positionateConnector(targetTopic) { + const targetPosition = targetTopic.getPosition(); + const offset = Topic.CONNECTOR_WIDTH / 2; + const targetTopicSize = targetTopic.getSize(); + let y; let + x; + if (targetTopic.getShapeType() == TopicShape.LINE) { + y = targetTopicSize.height; + } else { + y = targetTopicSize.height / 2; + } + y -= offset; - var connector = targetTopic.getShrinkConnector(); - if ($defined(connector)) { - if (Math.sign(targetPosition.x) > 0) { - x = targetTopicSize.width; - connector.setPosition(x, y); - } else { - x = -Topic.CONNECTOR_WIDTH; - } - connector.setPosition(x, y); - } - }, + const connector = targetTopic.getShrinkConnector(); + if ($defined(connector)) { + if (Math.sign(targetPosition.x) > 0) { + x = targetTopicSize.width; + connector.setPosition(x, y); + } else { + x = -Topic.CONNECTOR_WIDTH; + } + connector.setPosition(x, y); + } + }, - setStroke: function (color, style, opacity) { - this._line2d.setStroke(null, null, color, opacity); - }, + setStroke(color, style, opacity) { + this._line2d.setStroke(null, null, color, opacity); + }, - addToWorkspace: function (workspace) { - workspace.append(this._line2d); - this._line2d.moveToBack(); - }, + addToWorkspace(workspace) { + workspace.append(this._line2d); + this._line2d.moveToBack(); + }, - removeFromWorkspace: function (workspace) { - workspace.removeChild(this._line2d); - }, + removeFromWorkspace(workspace) { + workspace.removeChild(this._line2d); + }, - getTargetTopic: function () { - return this._targetTopic; - }, + getTargetTopic() { + return this._targetTopic; + }, - getSourceTopic: function () { - return this._sourceTopic; - }, + getSourceTopic() { + return this._sourceTopic; + }, - getLineType: function () { - return this._lineType; - }, + getLineType() { + return this._lineType; + }, - getLine: function () { - return this._line2d; - }, + getLine() { + return this._line2d; + }, - getModel: function () { - return this._model; - }, + getModel() { + return this._model; + }, - setModel: function (model) { - this._model = model; - }, + setModel(model) { + this._model = model; + }, - getType: function () { - return 'ConnectionLine'; - }, + getType() { + return 'ConnectionLine'; + }, - getId: function () { - return this._model.getId(); - }, + getId() { + return this._model.getId(); + }, - moveToBack: function () { - this._line2d.moveToBack(); - }, + moveToBack() { + this._line2d.moveToBack(); + }, - moveToFront: function () { - this._line2d.moveToFront(); - }, + moveToFront() { + this._line2d.moveToFront(); + }, }); ConnectionLine.getStrokeColor = function () { - return '#495879'; + return '#495879'; }; ConnectionLine.SIMPLE = 0; diff --git a/packages/mindplot/lib/components/ControlPoint.js b/packages/mindplot/lib/components/ControlPoint.js index c8d357c4..f623453e 100644 --- a/packages/mindplot/lib/components/ControlPoint.js +++ b/packages/mindplot/lib/components/ControlPoint.js @@ -15,194 +15,193 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const Core = require('@wismapping/core-js') +const Core = require('@wismapping/core-js'); + const core = Core(); -const web2D = require('@wismapping/web2d') +const web2D = require('@wismapping/web2d'); + const web2d = web2D(); -const Shape = require('./util/Shape').default +const Shape = require('./util/Shape').default; const ActionDispatcher = require('./ActionDispatcher').default; const ControlPoint = new Class({ - initialize: function () { - var control1 = new web2d.Elipse({ - width: 6, - height: 6, - stroke: '1 solid #6589de', - fillColor: 'gray', - visibility: false - }); - control1.setCursor('pointer'); + initialize() { + const control1 = new web2d.Elipse({ + width: 6, + height: 6, + stroke: '1 solid #6589de', + fillColor: 'gray', + visibility: false, + }); + control1.setCursor('pointer'); - var control2 = new web2d.Elipse({ - width: 6, - height: 6, - stroke: '1 solid #6589de', - fillColor: 'gray', - visibility: false - }); - control2.setCursor('pointer'); + const control2 = new web2d.Elipse({ + width: 6, + height: 6, + stroke: '1 solid #6589de', + fillColor: 'gray', + visibility: false, + }); + control2.setCursor('pointer'); - this._controlPointsController = [control1, control2]; - this._controlLines = [new web2d.Line({strokeColor: "#6589de", strokeWidth: 1, opacity: 0.3}), - new web2d.Line({strokeColor: "#6589de", strokeWidth: 1, opacity: 0.3})]; + this._controlPointsController = [control1, control2]; + this._controlLines = [new web2d.Line({ strokeColor: '#6589de', strokeWidth: 1, opacity: 0.3 }), + new web2d.Line({ strokeColor: '#6589de', strokeWidth: 1, opacity: 0.3 })]; - this._isBinded = false; - var me = this; - this._controlPointsController[0].addEvent('mousedown', function (event) { - (me._mouseDown)(event, ControlPoint.FROM, me); - }); - this._controlPointsController[0].addEvent('click', function (event) { - (me._mouseClick)(event); - }); - this._controlPointsController[0].addEvent('dblclick', function (event) { - (me._mouseClick)(event); - }); + this._isBinded = false; + const me = this; + this._controlPointsController[0].addEvent('mousedown', (event) => { + (me._mouseDown)(event, ControlPoint.FROM, me); + }); + this._controlPointsController[0].addEvent('click', (event) => { + (me._mouseClick)(event); + }); + this._controlPointsController[0].addEvent('dblclick', (event) => { + (me._mouseClick)(event); + }); - this._controlPointsController[1].addEvent('mousedown', function (event) { - (me._mouseDown)(event, ControlPoint.TO, me); - }); - this._controlPointsController[1].addEvent('click', function (event) { - (me._mouseClick)(event); - }); - this._controlPointsController[1].addEvent('dblclick', function (event) { - (me._mouseClick)(event); - }); - }, + this._controlPointsController[1].addEvent('mousedown', (event) => { + (me._mouseDown)(event, ControlPoint.TO, me); + }); + this._controlPointsController[1].addEvent('click', (event) => { + (me._mouseClick)(event); + }); + this._controlPointsController[1].addEvent('dblclick', (event) => { + (me._mouseClick)(event); + }); + }, - setLine: function (line) { - if ($defined(this._line)) { - this._removeLine(); - } - this._line = line; - this._createControlPoint(); - this._endPoint = []; - this._orignalCtrlPoint = []; - this._orignalCtrlPoint[0] = this._controls[0].clone(); - this._orignalCtrlPoint[1] = this._controls[1].clone(); - this._endPoint[0] = this._line.getLine().getFrom().clone(); - this._endPoint[1] = this._line.getLine().getTo().clone(); - }, - - redraw: function () { - if ($defined(this._line)) - this._createControlPoint(); - }, - - _createControlPoint: function () { - this._controls = this._line.getLine().getControlPoints(); - var pos = this._line.getLine().getFrom(); - this._controlPointsController[0].setPosition(this._controls[ControlPoint.FROM].x + pos.x, this._controls[ControlPoint.FROM].y + pos.y - 3); - this._controlLines[0].setFrom(pos.x, pos.y); - this._controlLines[0].setTo(this._controls[ControlPoint.FROM].x + pos.x + 3, this._controls[ControlPoint.FROM].y + pos.y); - pos = this._line.getLine().getTo(); - this._controlLines[1].setFrom(pos.x, pos.y); - this._controlLines[1].setTo(this._controls[ControlPoint.TO].x + pos.x + 3, this._controls[ControlPoint.TO].y + pos.y); - this._controlPointsController[1].setPosition(this._controls[ControlPoint.TO].x + pos.x, this._controls[ControlPoint.TO].y + pos.y - 3); - - }, - - _removeLine: function () { - - }, - - _mouseDown: function (event, point, me) { - if (!this._isBinded) { - this._isBinded = true; - this._mouseMoveFunction = function (event) { - (me._mouseMoveEvent)(event, point, me); - }; - - this._workspace.getScreenManager().addEvent('mousemove', this._mouseMoveFunction); - this._mouseUpFunction = function (event) { - (me._mouseUp)(event, point, me); - }; - this._workspace.getScreenManager().addEvent('mouseup', this._mouseUpFunction); - } - event.preventDefault(); - event.stopPropagation(); - return false; - }, - - _mouseMoveEvent: function (event, point) { - var screen = this._workspace.getScreenManager(); - var pos = screen.getWorkspaceMousePosition(event); - - var cords; - if (point == 0) { - cords = Shape.calculateRelationShipPointCoordinates(this._line.getSourceTopic(), pos); - this._line.setFrom(cords.x, cords.y); - this._line.setSrcControlPoint(new core.Point(pos.x - cords.x, pos.y - cords.y)); - } else { - cords = Shape.calculateRelationShipPointCoordinates(this._line.getTargetTopic(), pos); - this._line.setTo(cords.x, cords.y); - this._line.setDestControlPoint(new core.Point(pos.x - cords.x, pos.y - cords.y)); - } - - this._controls[point].x = (pos.x - cords.x); - this._controls[point].y = (pos.y - cords.y); - this._controlPointsController[point].setPosition(pos.x - 5, pos.y - 3); - this._controlLines[point].setFrom(cords.x, cords.y); - this._controlLines[point].setTo(pos.x - 2, pos.y); - this._line.getLine().updateLine(point); - - }, - - _mouseUp: function (event, point) { - this._workspace.getScreenManager().removeEvent('mousemove', this._mouseMoveFunction); - this._workspace.getScreenManager().removeEvent('mouseup', this._mouseUpFunction); - - var actionDispatcher = ActionDispatcher.getInstance(); - actionDispatcher.moveControlPoint(this, point); - this._isBinded = false; - }, - - _mouseClick: function (event) { - event.preventDefault(); - event.stopPropagation(); - return false; - }, - - setVisibility: function (visible) { - if (visible) { - this._controlLines[0].moveToFront(); - this._controlLines[1].moveToFront(); - this._controlPointsController[0].moveToFront(); - this._controlPointsController[1].moveToFront(); - } - this._controlPointsController[0].setVisibility(visible); - this._controlPointsController[1].setVisibility(visible); - this._controlLines[0].setVisibility(visible); - this._controlLines[1].setVisibility(visible); - }, - - addToWorkspace: function (workspace) { - this._workspace = workspace; - workspace.append(this._controlPointsController[0]); - workspace.append(this._controlPointsController[1]); - workspace.append(this._controlLines[0]); - workspace.append(this._controlLines[1]); - }, - - removeFromWorkspace: function (workspace) { - this._workspace = null; - workspace.removeChild(this._controlPointsController[0]); - workspace.removeChild(this._controlPointsController[1]); - workspace.removeChild(this._controlLines[0]); - workspace.removeChild(this._controlLines[1]); - }, - - getControlPoint: function (index) { - return this._controls[index]; - }, - - getOriginalEndPoint: function (index) { - return this._endPoint[index]; - }, - - getOriginalCtrlPoint: function (index) { - return this._orignalCtrlPoint[index]; + setLine(line) { + if ($defined(this._line)) { + this._removeLine(); } + this._line = line; + this._createControlPoint(); + this._endPoint = []; + this._orignalCtrlPoint = []; + this._orignalCtrlPoint[0] = this._controls[0].clone(); + this._orignalCtrlPoint[1] = this._controls[1].clone(); + this._endPoint[0] = this._line.getLine().getFrom().clone(); + this._endPoint[1] = this._line.getLine().getTo().clone(); + }, + + redraw() { + if ($defined(this._line)) this._createControlPoint(); + }, + + _createControlPoint() { + this._controls = this._line.getLine().getControlPoints(); + let pos = this._line.getLine().getFrom(); + this._controlPointsController[0].setPosition(this._controls[ControlPoint.FROM].x + pos.x, this._controls[ControlPoint.FROM].y + pos.y - 3); + this._controlLines[0].setFrom(pos.x, pos.y); + this._controlLines[0].setTo(this._controls[ControlPoint.FROM].x + pos.x + 3, this._controls[ControlPoint.FROM].y + pos.y); + pos = this._line.getLine().getTo(); + this._controlLines[1].setFrom(pos.x, pos.y); + this._controlLines[1].setTo(this._controls[ControlPoint.TO].x + pos.x + 3, this._controls[ControlPoint.TO].y + pos.y); + this._controlPointsController[1].setPosition(this._controls[ControlPoint.TO].x + pos.x, this._controls[ControlPoint.TO].y + pos.y - 3); + }, + + _removeLine() { + + }, + + _mouseDown(event, point, me) { + if (!this._isBinded) { + this._isBinded = true; + this._mouseMoveFunction = function (event) { + (me._mouseMoveEvent)(event, point, me); + }; + + this._workspace.getScreenManager().addEvent('mousemove', this._mouseMoveFunction); + this._mouseUpFunction = function (event) { + (me._mouseUp)(event, point, me); + }; + this._workspace.getScreenManager().addEvent('mouseup', this._mouseUpFunction); + } + event.preventDefault(); + event.stopPropagation(); + return false; + }, + + _mouseMoveEvent(event, point) { + const screen = this._workspace.getScreenManager(); + const pos = screen.getWorkspaceMousePosition(event); + + let cords; + if (point == 0) { + cords = Shape.calculateRelationShipPointCoordinates(this._line.getSourceTopic(), pos); + this._line.setFrom(cords.x, cords.y); + this._line.setSrcControlPoint(new core.Point(pos.x - cords.x, pos.y - cords.y)); + } else { + cords = Shape.calculateRelationShipPointCoordinates(this._line.getTargetTopic(), pos); + this._line.setTo(cords.x, cords.y); + this._line.setDestControlPoint(new core.Point(pos.x - cords.x, pos.y - cords.y)); + } + + this._controls[point].x = (pos.x - cords.x); + this._controls[point].y = (pos.y - cords.y); + this._controlPointsController[point].setPosition(pos.x - 5, pos.y - 3); + this._controlLines[point].setFrom(cords.x, cords.y); + this._controlLines[point].setTo(pos.x - 2, pos.y); + this._line.getLine().updateLine(point); + }, + + _mouseUp(event, point) { + this._workspace.getScreenManager().removeEvent('mousemove', this._mouseMoveFunction); + this._workspace.getScreenManager().removeEvent('mouseup', this._mouseUpFunction); + + const actionDispatcher = ActionDispatcher.getInstance(); + actionDispatcher.moveControlPoint(this, point); + this._isBinded = false; + }, + + _mouseClick(event) { + event.preventDefault(); + event.stopPropagation(); + return false; + }, + + setVisibility(visible) { + if (visible) { + this._controlLines[0].moveToFront(); + this._controlLines[1].moveToFront(); + this._controlPointsController[0].moveToFront(); + this._controlPointsController[1].moveToFront(); + } + this._controlPointsController[0].setVisibility(visible); + this._controlPointsController[1].setVisibility(visible); + this._controlLines[0].setVisibility(visible); + this._controlLines[1].setVisibility(visible); + }, + + addToWorkspace(workspace) { + this._workspace = workspace; + workspace.append(this._controlPointsController[0]); + workspace.append(this._controlPointsController[1]); + workspace.append(this._controlLines[0]); + workspace.append(this._controlLines[1]); + }, + + removeFromWorkspace(workspace) { + this._workspace = null; + workspace.removeChild(this._controlPointsController[0]); + workspace.removeChild(this._controlPointsController[1]); + workspace.removeChild(this._controlLines[0]); + workspace.removeChild(this._controlLines[1]); + }, + + getControlPoint(index) { + return this._controls[index]; + }, + + getOriginalEndPoint(index) { + return this._endPoint[index]; + }, + + getOriginalCtrlPoint(index) { + return this._orignalCtrlPoint[index]; + }, }); ControlPoint.FROM = 0; diff --git a/packages/mindplot/lib/components/Designer.js b/packages/mindplot/lib/components/Designer.js index 884dd417..1d3c0f0d 100644 --- a/packages/mindplot/lib/components/Designer.js +++ b/packages/mindplot/lib/components/Designer.js @@ -45,1004 +45,992 @@ const INodeModel = require('./model/INodeModel').default; const { TopicShape } = require('./model/INodeModel'); const Designer = new Class( - /** @lends Designer */ { - Extends: Events, - /** + /** @lends Designer */ { + Extends: Events, + /** * @constructs * @param {Object} options * @param {HTMLElement} divElement * @extends mindplot.Events */ - initialize: function (options, divElement) { - $assert(options, 'options must be defined'); - $assert(options.zoom, 'zoom must be defined'); - $assert(options.size, 'size must be defined'); - $assert(divElement, 'divElement must be defined'); + initialize(options, divElement) { + $assert(options, 'options must be defined'); + $assert(options.zoom, 'zoom must be defined'); + $assert(options.size, 'size must be defined'); + $assert(divElement, 'divElement must be defined'); - // Set up i18n location ... - Messages.init(options.locale); + // Set up i18n location ... + Messages.init(options.locale); - this._options = options; + this._options = options; - // Set full div elem render area ... - divElement.css(options.size); + // Set full div elem render area ... + divElement.css(options.size); - // Dispatcher manager ... - var commandContext = new CommandContext(this); - this._actionDispatcher = new StandaloneActionDispatcher(commandContext); + // Dispatcher manager ... + const commandContext = new CommandContext(this); + this._actionDispatcher = new StandaloneActionDispatcher(commandContext); - var me = this; - this._actionDispatcher.addEvent('modelUpdate', function (event) { - me.fireEvent('modelUpdate', event); - }); + const me = this; + this._actionDispatcher.addEvent('modelUpdate', (event) => { + me.fireEvent('modelUpdate', event); + }); - ActionDispatcher.setInstance(this._actionDispatcher); - this._model = new DesignerModel(options); + ActionDispatcher.setInstance(this._actionDispatcher); + this._model = new DesignerModel(options); - // Init Screen manager.. - var screenManager = new ScreenManager(divElement); - this._workspace = new Workspace(screenManager, this._model.getZoom()); + // Init Screen manager.. + const screenManager = new ScreenManager(divElement); + this._workspace = new Workspace(screenManager, this._model.getZoom()); - // Init layout manager ... - this._eventBussDispatcher = new EventBusDispatcher(this.getModel()); + // Init layout manager ... + this._eventBussDispatcher = new EventBusDispatcher(this.getModel()); - // Register events - if (!this.isReadOnly()) { - // Register mouse events ... - this._registerMouseEvents(); + // Register events + if (!this.isReadOnly()) { + // Register mouse events ... + this._registerMouseEvents(); - // Register keyboard events ... - DesignerKeyboard.register(this); + // Register keyboard events ... + DesignerKeyboard.register(this); - this._dragManager = this._buildDragManager(this._workspace); - } - this._registerWheelEvents(); + this._dragManager = this._buildDragManager(this._workspace); + } + this._registerWheelEvents(); - this._relPivot = new RelationshipPivot(this._workspace, this); + this._relPivot = new RelationshipPivot(this._workspace, this); - // Set editor working area ... - this.setViewPort(options.viewPort); + // Set editor working area ... + this.setViewPort(options.viewPort); - TopicEventDispatcher.configure(this.isReadOnly()); - this._clipboard = []; - }, + TopicEventDispatcher.configure(this.isReadOnly()); + this._clipboard = []; + }, - /** + /** * @private */ - _registerWheelEvents: function () { - var zoomFactor = 1.006; - var me = this; - // Zoom In and Zoom Out must active event - $(document).on('mousewheel', function (event) { - if (event.deltaY > 0) { - me.zoomIn(zoomFactor); - } else { - me.zoomOut(zoomFactor); - } - event.preventDefault(); - }); - }, + _registerWheelEvents() { + const zoomFactor = 1.006; + const me = this; + // Zoom In and Zoom Out must active event + $(document).on('mousewheel', (event) => { + if (event.deltaY > 0) { + me.zoomIn(zoomFactor); + } else { + me.zoomOut(zoomFactor); + } + event.preventDefault(); + }); + }, - /** + /** * @param {String} type the event type * @param {Function} listener * forwards to the TopicEventDispatcher or the parent Events class, depending on the type */ - addEvent: function (type, listener) { - if (type == TopicEvent.EDIT || type == TopicEvent.CLICK) { - var editor = TopicEventDispatcher.getInstance(); - editor.addEvent(type, listener); - } else { - this.parent(type, listener); - } - }, + addEvent(type, listener) { + if (type == TopicEvent.EDIT || type == TopicEvent.CLICK) { + const editor = TopicEventDispatcher.getInstance(); + editor.addEvent(type, listener); + } else { + this.parent(type, listener); + } + }, - /** + /** * @private */ - _registerMouseEvents: function () { - var workspace = this._workspace; - var screenManager = workspace.getScreenManager(); - var me = this; - // Initialize workspace event listeners. - screenManager.addEvent('update', function () { - // Topic must be set to his original state. All editors must be closed. - var topics = me.getModel().getTopics(); - _.each(topics, function (object) { - object.closeEditors(); - }); + _registerMouseEvents() { + const workspace = this._workspace; + const screenManager = workspace.getScreenManager(); + const me = this; + // Initialize workspace event listeners. + screenManager.addEvent('update', () => { + // Topic must be set to his original state. All editors must be closed. + const topics = me.getModel().getTopics(); + _.each(topics, (object) => { + object.closeEditors(); + }); - // Clean some selected nodes on event .. - if (me._cleanScreen) me._cleanScreen(); - }); + // Clean some selected nodes on event .. + if (me._cleanScreen) me._cleanScreen(); + }); - // Deselect on click ... - screenManager.addEvent('click', function (event) { - me.onObjectFocusEvent(null, event); - }); + // Deselect on click ... + screenManager.addEvent('click', (event) => { + me.onObjectFocusEvent(null, event); + }); - // Create nodes on double click... - screenManager.addEvent( - 'dblclick', - function (event) { - if (workspace.isWorkspaceEventsEnabled()) { - var mousePos = screenManager.getWorkspaceMousePosition(event); - var centralTopic = me.getModel().getCentralTopic(); - var model = me._createChildModel(centralTopic, mousePos); - this._actionDispatcher.addTopics([model], [centralTopic.getId()]); - } - }.bind(this) - ); - - // Register mouse drag and drop event ... - function noopHandler(evt) { - evt.stopPropagation(); - evt.preventDefault(); - } + // Create nodes on double click... + screenManager.addEvent( + 'dblclick', + (event) => { + if (workspace.isWorkspaceEventsEnabled()) { + const mousePos = screenManager.getWorkspaceMousePosition(event); + const centralTopic = me.getModel().getCentralTopic(); + const model = me._createChildModel(centralTopic, mousePos); + this._actionDispatcher.addTopics([model], [centralTopic.getId()]); + } }, + ); - /** + // Register mouse drag and drop event ... + function noopHandler(evt) { + evt.stopPropagation(); + evt.preventDefault(); + } + }, + + /** * @private * @param {mindplot.Workspace} workspace * @return {mindplot.DragManager} the new dragManager for the workspace with events * registered */ - _buildDragManager: function (workspace) { - var designerModel = this.getModel(); - var dragConnector = new DragConnector(designerModel, this._workspace); - var dragManager = new DragManager(workspace, this._eventBussDispatcher); - var topics = designerModel.getTopics(); + _buildDragManager(workspace) { + const designerModel = this.getModel(); + const dragConnector = new DragConnector(designerModel, this._workspace); + const dragManager = new DragManager(workspace, this._eventBussDispatcher); + const topics = designerModel.getTopics(); - dragManager.addEvent('startdragging', function () { - // Enable all mouse events. - for (var i = 0; i < topics.length; i++) { - topics[i].setMouseEventsEnabled(false); - } - }); + dragManager.addEvent('startdragging', () => { + // Enable all mouse events. + for (let i = 0; i < topics.length; i++) { + topics[i].setMouseEventsEnabled(false); + } + }); - dragManager.addEvent('dragging', function (event, dragTopic) { - dragTopic.updateFreeLayout(event); - if (!dragTopic.isFreeLayoutOn(event)) { - // The node is being drag. Is the connection still valid ? - dragConnector.checkConnection(dragTopic); + dragManager.addEvent('dragging', (event, dragTopic) => { + dragTopic.updateFreeLayout(event); + if (!dragTopic.isFreeLayoutOn(event)) { + // The node is being drag. Is the connection still valid ? + dragConnector.checkConnection(dragTopic); - if (!dragTopic.isVisible() && dragTopic.isConnected()) { - dragTopic.setVisibility(true); - } - } - }); + if (!dragTopic.isVisible() && dragTopic.isConnected()) { + dragTopic.setVisibility(true); + } + } + }); - dragManager.addEvent('enddragging', function (event, dragTopic) { - for (var i = 0; i < topics.length; i++) { - topics[i].setMouseEventsEnabled(true); - } - dragTopic.applyChanges(workspace); - }); + dragManager.addEvent('enddragging', (event, dragTopic) => { + for (let i = 0; i < topics.length; i++) { + topics[i].setMouseEventsEnabled(true); + } + dragTopic.applyChanges(workspace); + }); - return dragManager; - }, + return dragManager; + }, - /** + /** * @param {{width:Number, height:Number}} size * sets width and height of the workspace */ - setViewPort: function (size) { - this._workspace.setViewPort(size); - var model = this.getModel(); - this._workspace.setZoom(model.getZoom(), true); - }, + setViewPort(size) { + this._workspace.setViewPort(size); + const model = this.getModel(); + this._workspace.setZoom(model.getZoom(), true); + }, - /** + /** * @private * @param {mindplot.model.NodeModel} model * @param {Boolean} readOnly * @return {mindplot.CentralTopic|mindplot.MainTopic} the topic to the given model, * connected, added to the drag manager, with events registered - complying type & read mode */ - _buildNodeGraph: function (model, readOnly) { - // Create node graph ... - var topic = NodeGraph.create(model, { readOnly: readOnly }); - this.getModel().addTopic(topic); - var me = this; - // Add Topic events ... - if (!readOnly) { - // If a node had gained focus, clean the rest of the nodes ... - topic.addEvent('mousedown', function (event) { - me.onObjectFocusEvent(topic, event); - }); + _buildNodeGraph(model, readOnly) { + // Create node graph ... + const topic = NodeGraph.create(model, { readOnly }); + this.getModel().addTopic(topic); + const me = this; + // Add Topic events ... + if (!readOnly) { + // If a node had gained focus, clean the rest of the nodes ... + topic.addEvent('mousedown', (event) => { + me.onObjectFocusEvent(topic, event); + }); - // Register node listeners ... - if (topic.getType() != INodeModel.CENTRAL_TOPIC_TYPE) { - // Central Topic doesn't support to be dragged - this._dragManager.add(topic); - } - } + // Register node listeners ... + if (topic.getType() != INodeModel.CENTRAL_TOPIC_TYPE) { + // Central Topic doesn't support to be dragged + this._dragManager.add(topic); + } + } - // Connect Topic ... - var isConnected = model.isConnected(); - if (isConnected) { - // Improve this ... - var targetTopicModel = model.getParent(); - var targetTopic = null; + // Connect Topic ... + const isConnected = model.isConnected(); + if (isConnected) { + // Improve this ... + const targetTopicModel = model.getParent(); + let targetTopic = null; - var topics = this.getModel().getTopics(); - for (var i = 0; i < topics.length; i++) { - var t = topics[i]; - if (t.getModel() == targetTopicModel) { - targetTopic = t; - // Disconnect the node. It will be connected again later ... - model.disconnect(); - break; - } - } - $assert(targetTopic, 'Could not find a topic to connect'); - topic.connectTo(targetTopic, this._workspace); - } + const topics = this.getModel().getTopics(); + for (let i = 0; i < topics.length; i++) { + const t = topics[i]; + if (t.getModel() == targetTopicModel) { + targetTopic = t; + // Disconnect the node. It will be connected again later ... + model.disconnect(); + break; + } + } + $assert(targetTopic, 'Could not find a topic to connect'); + topic.connectTo(targetTopic, this._workspace); + } - topic.addEvent('ontblur', function () { - var topics = me.getModel().filterSelectedTopics(); - var rels = me.getModel().filterSelectedRelationships(); + topic.addEvent('ontblur', () => { + const topics = me.getModel().filterSelectedTopics(); + const rels = me.getModel().filterSelectedRelationships(); - if (topics.length == 0 || rels.length == 0) { - me.fireEvent('onblur'); - } - }); + if (topics.length == 0 || rels.length == 0) { + me.fireEvent('onblur'); + } + }); - topic.addEvent('ontfocus', function () { - var topics = me.getModel().filterSelectedTopics(); - var rels = me.getModel().filterSelectedRelationships(); + topic.addEvent('ontfocus', () => { + const topics = me.getModel().filterSelectedTopics(); + const rels = me.getModel().filterSelectedRelationships(); - if (topics.length == 1 || rels.length == 1) { - me.fireEvent('onfocus'); - } - }); + if (topics.length == 1 || rels.length == 1) { + me.fireEvent('onfocus'); + } + }); - return topic; - }, + return topic; + }, - /** + /** * @param {?mindplot.Topic} currentObject * @param {Event=} event * sets focus to the given currentObject and removes it from any other objects if not * triggered with Ctrl pressed */ - onObjectFocusEvent: function (currentObject, event) { - // Close node editors .. - var topics = this.getModel().getTopics(); - _.each(topics, function (topic) { - topic.closeEditors(); - }); + onObjectFocusEvent(currentObject, event) { + // Close node editors .. + const topics = this.getModel().getTopics(); + _.each(topics, (topic) => { + topic.closeEditors(); + }); - var model = this.getModel(); - var objects = model.getEntities(); - _.each(objects, function (object) { - // Disable all nodes on focus but not the current if Ctrl key isn't being pressed - if (!$defined(event) || (!event.ctrlKey && !event.metaKey)) { - if (object.isOnFocus() && object != currentObject) { - object.setOnFocus(false); - } - } - }); - }, + const model = this.getModel(); + const objects = model.getEntities(); + _.each(objects, (object) => { + // Disable all nodes on focus but not the current if Ctrl key isn't being pressed + if (!$defined(event) || (!event.ctrlKey && !event.metaKey)) { + if (object.isOnFocus() && object != currentObject) { + object.setOnFocus(false); + } + } + }); + }, - /** sets focus to all model entities, i.e. relationships and topics */ - selectAll: function () { - var model = this.getModel(); - var objects = model.getEntities(); - _.each(objects, function (object) { - object.setOnFocus(true); - }); - }, + /** sets focus to all model entities, i.e. relationships and topics */ + selectAll() { + const model = this.getModel(); + const objects = model.getEntities(); + _.each(objects, (object) => { + object.setOnFocus(true); + }); + }, - /** removes focus from all model entities, i.e. relationships and topics */ - deselectAll: function () { - var objects = this.getModel().getEntities(); - _.each(objects, function (object) { - object.setOnFocus(false); - }); - }, + /** removes focus from all model entities, i.e. relationships and topics */ + deselectAll() { + const objects = this.getModel().getEntities(); + _.each(objects, (object) => { + object.setOnFocus(false); + }); + }, - /** + /** * Set the zoom of the map * @param {Number} zoom number between 0.3 and 1.9 */ - setZoom: function (zoom) { - if (zoom > 1.9 || zoom < 0.3) { - $notify($msg('ZOOM_IN_ERROR')); - return; - } - this.getModel().setZoom(zoom); - this._workspace.setZoom(zoom); - }, + setZoom(zoom) { + if (zoom > 1.9 || zoom < 0.3) { + $notify($msg('ZOOM_IN_ERROR')); + return; + } + this.getModel().setZoom(zoom); + this._workspace.setZoom(zoom); + }, - /** + /** * @param {Number=} factor * zoom out by the given factor, or 1.2, if undefined */ - zoomOut: function (factor) { - if (!factor) factor = 1.2; + zoomOut(factor) { + if (!factor) factor = 1.2; - var model = this.getModel(); - var scale = model.getZoom() * factor; - if (scale <= 1.9) { - model.setZoom(scale); - this._workspace.setZoom(scale); - } else { - $notify($msg('ZOOM_ERROR')); - } - }, + const model = this.getModel(); + const scale = model.getZoom() * factor; + if (scale <= 1.9) { + model.setZoom(scale); + this._workspace.setZoom(scale); + } else { + $notify($msg('ZOOM_ERROR')); + } + }, - /** + /** * @param {Number=} factor * zoom in by the given factor, or 1.2, if undefined */ - zoomIn: function (factor) { - if (!factor) factor = 1.2; + zoomIn(factor) { + if (!factor) factor = 1.2; - var model = this.getModel(); - var scale = model.getZoom() / factor; + const model = this.getModel(); + const scale = model.getZoom() / factor; - if (scale >= 0.3) { - model.setZoom(scale); - this._workspace.setZoom(scale); - } else { - $notify($msg('ZOOM_ERROR')); - } - }, + if (scale >= 0.3) { + model.setZoom(scale); + this._workspace.setZoom(scale); + } else { + $notify($msg('ZOOM_ERROR')); + } + }, - /** copy selected topics to a private clipboard */ - copyToClipboard: function () { - var topics = this.getModel().filterSelectedTopics(); - if (topics.length <= 0) { - // If there are more than one node selected, - $notify($msg('AT_LEAST_ONE_TOPIC_MUST_BE_SELECTED')); - return; - } + /** copy selected topics to a private clipboard */ + copyToClipboard() { + let topics = this.getModel().filterSelectedTopics(); + if (topics.length <= 0) { + // If there are more than one node selected, + $notify($msg('AT_LEAST_ONE_TOPIC_MUST_BE_SELECTED')); + return; + } - // Exclude central topic .. - topics = topics.filter(function (topic) { - return !topic.isCentralTopic(); - }); + // Exclude central topic .. + topics = topics.filter((topic) => !topic.isCentralTopic()); - this._clipboard = topics.map(function (topic) { - var nodeModel = topic.getModel().deepCopy(); + this._clipboard = topics.map((topic) => { + const nodeModel = topic.getModel().deepCopy(); - // Change position to make the new topic evident... - var pos = nodeModel.getPosition(); - nodeModel.setPosition(pos.x + 60 * Math.sign(pos.x), pos.y + 30); + // Change position to make the new topic evident... + const pos = nodeModel.getPosition(); + nodeModel.setPosition(pos.x + 60 * Math.sign(pos.x), pos.y + 30); - return nodeModel; - }); + return nodeModel; + }); - $notify($msg('SELECTION_COPIED_TO_CLIPBOARD')); - }, + $notify($msg('SELECTION_COPIED_TO_CLIPBOARD')); + }, - /** paste clipboard contents to the mindmap */ - pasteClipboard: function () { - if (this._clipboard.length == 0) { - $notify($msg('CLIPBOARD_IS_EMPTY')); - return; - } - this._actionDispatcher.addTopics(this._clipboard); - this._clipboard = []; - }, + /** paste clipboard contents to the mindmap */ + pasteClipboard() { + if (this._clipboard.length == 0) { + $notify($msg('CLIPBOARD_IS_EMPTY')); + return; + } + this._actionDispatcher.addTopics(this._clipboard); + this._clipboard = []; + }, - /** @return {mindplot.DesignerModel} model */ - getModel: function () { - return this._model; - }, + /** @return {mindplot.DesignerModel} model */ + getModel() { + return this._model; + }, - /** collapse the subtree of the selected topic */ - shrinkSelectedBranch: function () { - var nodes = this.getModel().filterSelectedTopics(); - if (nodes.length <= 0 || nodes.length != 1) { - // If there are more than one node selected, - $notify($msg('ONLY_ONE_TOPIC_MUST_BE_SELECTED_COLLAPSE')); - return; - } - // Execute event ... - var topic = nodes[0]; - if (topic.getType() != INodeModel.CENTRAL_TOPIC_TYPE) { - this._actionDispatcher.shrinkBranch([topic.getId()], !topic.areChildrenShrunken()); - } - }, + /** collapse the subtree of the selected topic */ + shrinkSelectedBranch() { + const nodes = this.getModel().filterSelectedTopics(); + if (nodes.length <= 0 || nodes.length != 1) { + // If there are more than one node selected, + $notify($msg('ONLY_ONE_TOPIC_MUST_BE_SELECTED_COLLAPSE')); + return; + } + // Execute event ... + const topic = nodes[0]; + if (topic.getType() != INodeModel.CENTRAL_TOPIC_TYPE) { + this._actionDispatcher.shrinkBranch([topic.getId()], !topic.areChildrenShrunken()); + } + }, - /** create a NodeModel for the selected node's child and add it via the ActionDispatcher */ - createChildForSelectedNode: function () { - var nodes = this.getModel().filterSelectedTopics(); - if (nodes.length <= 0) { - // If there are more than one node selected, - $notify($msg('ONE_TOPIC_MUST_BE_SELECTED')); - return; - } - if (nodes.length != 1) { - // If there are more than one node selected, - $notify($msg('ONLY_ONE_TOPIC_MUST_BE_SELECTED')); - return; - } + /** create a NodeModel for the selected node's child and add it via the ActionDispatcher */ + createChildForSelectedNode() { + const nodes = this.getModel().filterSelectedTopics(); + if (nodes.length <= 0) { + // If there are more than one node selected, + $notify($msg('ONE_TOPIC_MUST_BE_SELECTED')); + return; + } + if (nodes.length != 1) { + // If there are more than one node selected, + $notify($msg('ONLY_ONE_TOPIC_MUST_BE_SELECTED')); + return; + } - // Add new node ... - var parentTopic = nodes[0]; - var parentTopicId = parentTopic.getId(); - var childModel = this._createChildModel(parentTopic); + // Add new node ... + const parentTopic = nodes[0]; + const parentTopicId = parentTopic.getId(); + const childModel = this._createChildModel(parentTopic); - // Execute event ... - this._actionDispatcher.addTopics([childModel], [parentTopicId]); - }, + // Execute event ... + this._actionDispatcher.addTopics([childModel], [parentTopicId]); + }, - /** + /** * @private */ - _copyNodeProps: function (sourceModel, targetModel) { - // I don't copy the font size if the target is the source is the central topic. - if (sourceModel.getType() != INodeModel.CENTRAL_TOPIC_TYPE) { - var fontSize = sourceModel.getFontSize(); - if (fontSize) { - targetModel.setFontSize(fontSize); - } - } + _copyNodeProps(sourceModel, targetModel) { + // I don't copy the font size if the target is the source is the central topic. + if (sourceModel.getType() != INodeModel.CENTRAL_TOPIC_TYPE) { + const fontSize = sourceModel.getFontSize(); + if (fontSize) { + targetModel.setFontSize(fontSize); + } + } - var fontFamily = sourceModel.getFontFamily(); - if (fontFamily) { - targetModel.setFontFamily(fontFamily); - } + const fontFamily = sourceModel.getFontFamily(); + if (fontFamily) { + targetModel.setFontFamily(fontFamily); + } - var fontColor = sourceModel.getFontColor(); - if (fontColor) { - targetModel.setFontColor(fontColor); - } + const fontColor = sourceModel.getFontColor(); + if (fontColor) { + targetModel.setFontColor(fontColor); + } - var fontWeight = sourceModel.getFontWeight(); - if (fontWeight) { - targetModel.setFontWeight(fontWeight); - } + const fontWeight = sourceModel.getFontWeight(); + if (fontWeight) { + targetModel.setFontWeight(fontWeight); + } - var fontStyle = sourceModel.getFontStyle(); - if (fontStyle) { - targetModel.setFontStyle(fontStyle); - } + const fontStyle = sourceModel.getFontStyle(); + if (fontStyle) { + targetModel.setFontStyle(fontStyle); + } - var shape = sourceModel.getShapeType(); - if (shape) { - targetModel.setShapeType(shape); - } + const shape = sourceModel.getShapeType(); + if (shape) { + targetModel.setShapeType(shape); + } - var borderColor = sourceModel.getBorderColor(); - if (borderColor) { - targetModel.setBorderColor(borderColor); - } + const borderColor = sourceModel.getBorderColor(); + if (borderColor) { + targetModel.setBorderColor(borderColor); + } - var backgroundColor = sourceModel.getBackgroundColor(); - if (backgroundColor) { - targetModel.setBackgroundColor(backgroundColor); - } - }, + const backgroundColor = sourceModel.getBackgroundColor(); + if (backgroundColor) { + targetModel.setBackgroundColor(backgroundColor); + } + }, - /** + /** * @private * @param {mindplot.Topic} topic the parent topic of the child to create the NodeModel for * @param {core.Point} mousePos the mouse position * @return {mindplot.NodeModel} the node model for the new child */ - _createChildModel: function (topic, mousePos) { - // Create a new node ... - var parentModel = topic.getModel(); - var mindmap = parentModel.getMindmap(); - var childModel = mindmap.createNode(); + _createChildModel(topic, mousePos) { + // Create a new node ... + const parentModel = topic.getModel(); + const mindmap = parentModel.getMindmap(); + const childModel = mindmap.createNode(); - // Create a new node ... - var layoutManager = this._eventBussDispatcher.getLayoutManager(); - var result = layoutManager.predict(topic.getId(), null, mousePos); - childModel.setOrder(result.order); + // Create a new node ... + const layoutManager = this._eventBussDispatcher.getLayoutManager(); + const result = layoutManager.predict(topic.getId(), null, mousePos); + childModel.setOrder(result.order); - var position = result.position; - childModel.setPosition(position.x, position.y); + const { position } = result; + childModel.setPosition(position.x, position.y); - this._copyNodeProps(parentModel, childModel); + this._copyNodeProps(parentModel, childModel); - return childModel; - }, + return childModel; + }, - /** + /** * @param {Events} event * @param {mindplot.model.NodeModel} model * @todo not used */ - addDraggedNode: function (event, model) { - $assert(event, 'event can not be null'); - $assert(model, 'model can not be null'); + addDraggedNode(event, model) { + $assert(event, 'event can not be null'); + $assert(model, 'model can not be null'); - // Position far from the visual area ... - model.setPosition(1000, 1000); + // Position far from the visual area ... + model.setPosition(1000, 1000); - this._actionDispatcher.addTopics([model]); - var topic = this.getModel().findTopicById(model.getId()); + this._actionDispatcher.addTopics([model]); + const topic = this.getModel().findTopicById(model.getId()); - // Simulate a mouse down event to start the dragging ... - topic.fireEvent('mousedown', event); - }, + // Simulate a mouse down event to start the dragging ... + topic.fireEvent('mousedown', event); + }, - /** + /** * creates a sibling or child node of the selected node, if the selected node is the * central topic */ - createSiblingForSelectedNode: function () { - var nodes = this.getModel().filterSelectedTopics(); - if (nodes.length <= 0) { - // If there are no nodes selected, - $notify($msg('ONE_TOPIC_MUST_BE_SELECTED')); - return; - } - if (nodes.length > 1) { - // If there are more than one node selected, - $notify($msg('ONLY_ONE_TOPIC_MUST_BE_SELECTED')); - return; - } + createSiblingForSelectedNode() { + const nodes = this.getModel().filterSelectedTopics(); + if (nodes.length <= 0) { + // If there are no nodes selected, + $notify($msg('ONE_TOPIC_MUST_BE_SELECTED')); + return; + } + if (nodes.length > 1) { + // If there are more than one node selected, + $notify($msg('ONLY_ONE_TOPIC_MUST_BE_SELECTED')); + return; + } - var topic = nodes[0]; - if (!topic.getOutgoingConnectedTopic()) { - // Central topic and isolated topics .... - // Central topic doesn't have siblings ... - this.createChildForSelectedNode(); - } else { - var parentTopic = topic.getOutgoingConnectedTopic(); - var siblingModel = this._createSiblingModel(topic); + const topic = nodes[0]; + if (!topic.getOutgoingConnectedTopic()) { + // Central topic and isolated topics .... + // Central topic doesn't have siblings ... + this.createChildForSelectedNode(); + } else { + const parentTopic = topic.getOutgoingConnectedTopic(); + const siblingModel = this._createSiblingModel(topic); - // Hack: if parent is central topic, add node below not on opposite side. - // This should be done in the layout - if (parentTopic.getType() == INodeModel.CENTRAL_TOPIC_TYPE) { - siblingModel.setOrder(topic.getOrder() + 2); - } + // Hack: if parent is central topic, add node below not on opposite side. + // This should be done in the layout + if (parentTopic.getType() == INodeModel.CENTRAL_TOPIC_TYPE) { + siblingModel.setOrder(topic.getOrder() + 2); + } - var parentTopicId = parentTopic.getId(); - this._actionDispatcher.addTopics([siblingModel], [parentTopicId]); - } - }, + const parentTopicId = parentTopic.getId(); + this._actionDispatcher.addTopics([siblingModel], [parentTopicId]); + } + }, - /** + /** * @private * @param {mindplot.Topic} topic the topic to create the sibling to * @return {mindplot.NodeModel} the node model of the sibling */ - _createSiblingModel: function (topic) { - var result = null; - var parentTopic = topic.getOutgoingConnectedTopic(); - if (parentTopic != null) { - // Create a new node ... - var model = topic.getModel(); - var mindmap = model.getMindmap(); - result = mindmap.createNode(); + _createSiblingModel(topic) { + let result = null; + const parentTopic = topic.getOutgoingConnectedTopic(); + if (parentTopic != null) { + // Create a new node ... + var model = topic.getModel(); + const mindmap = model.getMindmap(); + result = mindmap.createNode(); - // Create a new node ... - var order = topic.getOrder() + 1; - result.setOrder(order); - result.setPosition(10, 10); // Set a dummy position ... - } + // Create a new node ... + const order = topic.getOrder() + 1; + result.setOrder(order); + result.setPosition(10, 10); // Set a dummy position ... + } - this._copyNodeProps(model, result); + this._copyNodeProps(model, result); - return result; - }, + return result; + }, - /** + /** * @param {Event} event */ - showRelPivot: function (event) { - var nodes = this.getModel().filterSelectedTopics(); - if (nodes.length <= 0) { - // This could not happen ... - $notify($msg('RELATIONSHIP_COULD_NOT_BE_CREATED')); - return; - } + showRelPivot(event) { + const nodes = this.getModel().filterSelectedTopics(); + if (nodes.length <= 0) { + // This could not happen ... + $notify($msg('RELATIONSHIP_COULD_NOT_BE_CREATED')); + return; + } - // Current mouse position .... - var screen = this._workspace.getScreenManager(); - var pos = screen.getWorkspaceMousePosition(event); + // Current mouse position .... + const screen = this._workspace.getScreenManager(); + const pos = screen.getWorkspaceMousePosition(event); - // create a connection ... - this._relPivot.start(nodes[0], pos); - }, + // create a connection ... + this._relPivot.start(nodes[0], pos); + }, - /** @return {{zoom:Number}} the zoom */ - getMindmapProperties: function () { - var model = this.getModel(); - return { zoom: model.getZoom() }; - }, + /** @return {{zoom:Number}} the zoom */ + getMindmapProperties() { + const model = this.getModel(); + return { zoom: model.getZoom() }; + }, - /** + /** * @param {mindplot.Mindmap} mindmapModel * @throws will throw an error if mindmapModel is null or undefined */ - loadMap: function (mindmapModel) { - $assert(mindmapModel, 'mindmapModel can not be null'); - this._mindmap = mindmapModel; + loadMap(mindmapModel) { + $assert(mindmapModel, 'mindmapModel can not be null'); + this._mindmap = mindmapModel; - // Init layout manager ... - var size = { width: 25, height: 25 }; - var layoutManager = new LayoutManager(mindmapModel.getCentralTopic().getId(), size); - var me = this; - layoutManager.addEvent('change', function (event) { - var id = event.getId(); - var topic = me.getModel().findTopicById(id); - topic.setPosition(event.getPosition()); - topic.setOrder(event.getOrder()); - }); - this._eventBussDispatcher.setLayoutManager(layoutManager); + // Init layout manager ... + const size = { width: 25, height: 25 }; + const layoutManager = new LayoutManager(mindmapModel.getCentralTopic().getId(), size); + const me = this; + layoutManager.addEvent('change', (event) => { + const id = event.getId(); + const topic = me.getModel().findTopicById(id); + topic.setPosition(event.getPosition()); + topic.setOrder(event.getOrder()); + }); + this._eventBussDispatcher.setLayoutManager(layoutManager); - // Building node graph ... - var branches = mindmapModel.getBranches(); - for (var i = 0; i < branches.length; i++) { - // NodeModel -> NodeGraph ... - var nodeModel = branches[i]; - var nodeGraph = this.nodeModelToNodeGraph(nodeModel); + // Building node graph ... + const branches = mindmapModel.getBranches(); + for (let i = 0; i < branches.length; i++) { + // NodeModel -> NodeGraph ... + const nodeModel = branches[i]; + const nodeGraph = this.nodeModelToNodeGraph(nodeModel); - // Update shrink render state... - nodeGraph.setBranchVisibility(true); - } + // Update shrink render state... + nodeGraph.setBranchVisibility(true); + } - var relationships = mindmapModel.getRelationships(); - for (var j = 0; j < relationships.length; j++) { - this._relationshipModelToRelationship(relationships[j]); - } + const relationships = mindmapModel.getRelationships(); + for (let j = 0; j < relationships.length; j++) { + this._relationshipModelToRelationship(relationships[j]); + } - // Place the focus on the Central Topic - var centralTopic = this.getModel().getCentralTopic(); - this.goToNode(centralTopic); + // Place the focus on the Central Topic + const centralTopic = this.getModel().getCentralTopic(); + this.goToNode(centralTopic); - // Finally, sort the map ... - EventBus.instance.fireEvent(EventBus.events.DoLayout); + // Finally, sort the map ... + EventBus.instance.fireEvent(EventBus.events.DoLayout); - this.fireEvent('loadSuccess'); - }, + this.fireEvent('loadSuccess'); + }, - /** */ - getMindmap: function () { - return this._mindmap; - }, + /** */ + getMindmap() { + return this._mindmap; + }, - /** */ - undo: function () { - // @Todo: This is a hack... - this._actionDispatcher._actionRunner.undo(); - }, + /** */ + undo() { + // @Todo: This is a hack... + this._actionDispatcher._actionRunner.undo(); + }, - /** */ - redo: function () { - this._actionDispatcher._actionRunner.redo(); - }, + /** */ + redo() { + this._actionDispatcher._actionRunner.redo(); + }, - /** */ - isReadOnly: function () { - return this._options.readOnly; - }, + /** */ + isReadOnly() { + return this._options.readOnly; + }, - /** + /** * @param {mindplot.model.NodeModel} nodeModel * @return {mindplot.Topic} the topic (extends mindplot.NodeGraph) created to the model */ - nodeModelToNodeGraph: function (nodeModel) { - $assert(nodeModel, 'Node model can not be null'); - var children = nodeModel.getChildren().slice(); - children = children.sort(function (a, b) { - return a.getOrder() - b.getOrder(); - }); + nodeModelToNodeGraph(nodeModel) { + $assert(nodeModel, 'Node model can not be null'); + let children = nodeModel.getChildren().slice(); + children = children.sort((a, b) => a.getOrder() - b.getOrder()); - var nodeGraph = this._buildNodeGraph(nodeModel, this.isReadOnly()); - nodeGraph.setVisibility(false); + const nodeGraph = this._buildNodeGraph(nodeModel, this.isReadOnly()); + nodeGraph.setVisibility(false); - this._workspace.append(nodeGraph); - for (var i = 0; i < children.length; i++) { - var child = children[i]; - if ($defined(child)) this.nodeModelToNodeGraph(child); - } + this._workspace.append(nodeGraph); + for (let i = 0; i < children.length; i++) { + const child = children[i]; + if ($defined(child)) this.nodeModelToNodeGraph(child); + } - return nodeGraph; - }, + return nodeGraph; + }, - /** + /** * @private * @param {mindplot.model.RelationshipModel} model * @return {mindplot.Relationship} the relationship created to the model * @throws will throw an error if model is null or undefined */ - _relationshipModelToRelationship: function (model) { - $assert(model, 'Node model can not be null'); + _relationshipModelToRelationship(model) { + $assert(model, 'Node model can not be null'); - var result = this._buildRelationshipShape(model); + const result = this._buildRelationshipShape(model); - var sourceTopic = result.getSourceTopic(); - sourceTopic.addRelationship(result); + const sourceTopic = result.getSourceTopic(); + sourceTopic.addRelationship(result); - var targetTopic = result.getTargetTopic(); - targetTopic.addRelationship(result); + const targetTopic = result.getTargetTopic(); + targetTopic.addRelationship(result); - result.setVisibility(sourceTopic.isVisible() && targetTopic.isVisible()); + result.setVisibility(sourceTopic.isVisible() && targetTopic.isVisible()); - this._workspace.append(result); - return result; - }, + this._workspace.append(result); + return result; + }, - /** + /** * @param {mindplot.model.RelationshipModel} model * @return {mindplot.Relationship} the relationship added to the mindmap */ - addRelationship: function (model) { - var mindmap = this.getMindmap(); - mindmap.addRelationship(model); - return this._relationshipModelToRelationship(model); - }, + addRelationship(model) { + const mindmap = this.getMindmap(); + mindmap.addRelationship(model); + return this._relationshipModelToRelationship(model); + }, - /** + /** * deletes the relationship from the linked topics, DesignerModel, Workspace and Mindmap * @param {mindplot.Relationship} rel the relationship to delete */ - deleteRelationship: function (rel) { - var sourceTopic = rel.getSourceTopic(); - sourceTopic.deleteRelationship(rel); + deleteRelationship(rel) { + const sourceTopic = rel.getSourceTopic(); + sourceTopic.deleteRelationship(rel); - var targetTopic = rel.getTargetTopic(); - targetTopic.deleteRelationship(rel); + const targetTopic = rel.getTargetTopic(); + targetTopic.deleteRelationship(rel); - this.getModel().removeRelationship(rel); - this._workspace.removeChild(rel); + this.getModel().removeRelationship(rel); + this._workspace.removeChild(rel); - var mindmap = this.getMindmap(); - mindmap.deleteRelationship(rel.getModel()); - }, + const mindmap = this.getMindmap(); + mindmap.deleteRelationship(rel.getModel()); + }, - /** + /** * @private * @param {mindplot.model.RelationshipModel} model * @return {mindplot.Relationship} the new relationship with events registered * @throws will throw an error if the target topic cannot be found */ - _buildRelationshipShape: function (model) { - var dmodel = this.getModel(); + _buildRelationshipShape(model) { + const dmodel = this.getModel(); - var sourceTopicId = model.getFromNode(); - var sourceTopic = dmodel.findTopicById(sourceTopicId); + const sourceTopicId = model.getFromNode(); + const sourceTopic = dmodel.findTopicById(sourceTopicId); - var targetTopicId = model.getToNode(); - var targetTopic = dmodel.findTopicById(targetTopicId); - $assert( - targetTopic, - 'targetTopic could not be found:' + - targetTopicId + - dmodel.getTopics().map(function (e) { - return e.getId(); - }) - ); + const targetTopicId = model.getToNode(); + const targetTopic = dmodel.findTopicById(targetTopicId); + $assert( + targetTopic, + `targetTopic could not be found:${ + targetTopicId + }${dmodel.getTopics().map((e) => e.getId())}`, + ); - // Build relationship line .... - var result = new Relationship(sourceTopic, targetTopic, model); - var me = this; + // Build relationship line .... + const result = new Relationship(sourceTopic, targetTopic, model); + const me = this; - result.addEvent('ontblur', function () { - var topics = me.getModel().filterSelectedTopics(); - var rels = me.getModel().filterSelectedRelationships(); + result.addEvent('ontblur', () => { + const topics = me.getModel().filterSelectedTopics(); + const rels = me.getModel().filterSelectedRelationships(); - if (topics.length == 0 || rels.length == 0) { - me.fireEvent('onblur'); - } - }); + if (topics.length == 0 || rels.length == 0) { + me.fireEvent('onblur'); + } + }); - result.addEvent('ontfocus', function () { - var topics = me.getModel().filterSelectedTopics(); - var rels = me.getModel().filterSelectedRelationships(); + result.addEvent('ontfocus', () => { + const topics = me.getModel().filterSelectedTopics(); + const rels = me.getModel().filterSelectedRelationships(); - if (topics.length == 1 || rels.length == 1) { - me.fireEvent('onfocus'); - } - }); + if (topics.length == 1 || rels.length == 1) { + me.fireEvent('onfocus'); + } + }); - // Append it to the workspace ... - dmodel.addRelationship(result); + // Append it to the workspace ... + dmodel.addRelationship(result); - return result; - }, + return result; + }, - /** + /** * @param {mindplot.Topic} node the topic to remove * removes the given topic and its children from Workspace, DesignerModel and NodeModel */ - removeTopic: function (node) { - if (!node.isCentralTopic()) { - var parent = node._parent; - node.disconnect(this._workspace); + removeTopic(node) { + if (!node.isCentralTopic()) { + const parent = node._parent; + node.disconnect(this._workspace); - //remove children - while (node.getChildren().length > 0) { - this.removeTopic(node.getChildren()[0]); - } + // remove children + while (node.getChildren().length > 0) { + this.removeTopic(node.getChildren()[0]); + } - this._workspace.removeChild(node); - this.getModel().removeTopic(node); + this._workspace.removeChild(node); + this.getModel().removeTopic(node); - // Delete this node from the model... - var model = node.getModel(); - model.deleteNode(); + // Delete this node from the model... + const model = node.getModel(); + model.deleteNode(); - if ($defined(parent)) { - this.goToNode(parent); - } - } - }, + if ($defined(parent)) { + this.goToNode(parent); + } + } + }, - /** + /** * @private */ - _resetEdition: function () { - var screenManager = this._workspace.getScreenManager(); - screenManager.fireEvent('update'); - screenManager.fireEvent('mouseup'); - this._relPivot.dispose(); - }, + _resetEdition() { + const screenManager = this._workspace.getScreenManager(); + screenManager.fireEvent('update'); + screenManager.fireEvent('mouseup'); + this._relPivot.dispose(); + }, - /** */ - deleteSelectedEntities: function () { - // Is there some action in progress ?. - this._resetEdition(); + /** */ + deleteSelectedEntities() { + // Is there some action in progress ?. + this._resetEdition(); - var topics = this.getModel().filterSelectedTopics(); - var relation = this.getModel().filterSelectedRelationships(); - if (topics.length <= 0 && relation.length <= 0) { - // If there are more than one node selected, - $notify($msg('ENTITIES_COULD_NOT_BE_DELETED')); - return; - } else if (topics.length == 1 && topics[0].isCentralTopic()) { - $notify($msg('CENTRAL_TOPIC_CAN_NOT_BE_DELETED')); - return; - } + const topics = this.getModel().filterSelectedTopics(); + const relation = this.getModel().filterSelectedRelationships(); + if (topics.length <= 0 && relation.length <= 0) { + // If there are more than one node selected, + $notify($msg('ENTITIES_COULD_NOT_BE_DELETED')); + return; + } if (topics.length == 1 && topics[0].isCentralTopic()) { + $notify($msg('CENTRAL_TOPIC_CAN_NOT_BE_DELETED')); + return; + } - // If the central topic has been selected, I must filter ir - var topicIds = topics - .filter(function (topic) { - return !topic.isCentralTopic(); - }) - .map(function (topic) { - return topic.getId(); - }); + // If the central topic has been selected, I must filter ir + const topicIds = topics + .filter((topic) => !topic.isCentralTopic()) + .map((topic) => topic.getId()); - var relIds = relation.map(function (rel) { - return rel.getId(); - }); + const relIds = relation.map((rel) => rel.getId()); - // Finally delete the topics ... - if (topicIds.length > 0 || relIds.length > 0) { - this._actionDispatcher.deleteEntities(topicIds, relIds); - } - }, + // Finally delete the topics ... + if (topicIds.length > 0 || relIds.length > 0) { + this._actionDispatcher.deleteEntities(topicIds, relIds); + } + }, - /** */ - changeFontFamily: function (font) { - var topicsIds = this.getModel().filterTopicsIds(); - if (topicsIds.length > 0) { - this._actionDispatcher.changeFontFamilyToTopic(topicsIds, font); - } - }, + /** */ + changeFontFamily(font) { + const topicsIds = this.getModel().filterTopicsIds(); + if (topicsIds.length > 0) { + this._actionDispatcher.changeFontFamilyToTopic(topicsIds, font); + } + }, - /** */ - changeFontStyle: function () { - var topicsIds = this.getModel().filterTopicsIds(); - if (topicsIds.length > 0) { - this._actionDispatcher.changeFontStyleToTopic(topicsIds); - } - }, + /** */ + changeFontStyle() { + const topicsIds = this.getModel().filterTopicsIds(); + if (topicsIds.length > 0) { + this._actionDispatcher.changeFontStyleToTopic(topicsIds); + } + }, - /** */ - changeFontColor: function (color) { - $assert(color, 'color can not be null'); + /** */ + changeFontColor(color) { + $assert(color, 'color can not be null'); - var topicsIds = this.getModel().filterTopicsIds(); - if (topicsIds.length > 0) { - this._actionDispatcher.changeFontColorToTopic(topicsIds, color); - } - }, + const topicsIds = this.getModel().filterTopicsIds(); + if (topicsIds.length > 0) { + this._actionDispatcher.changeFontColorToTopic(topicsIds, color); + } + }, - /** */ - changeBackgroundColor: function (color) { - var validateFunc = function (topic) { - return topic.getShapeType() != TopicShape.LINE; - }; - var validateError = 'Color can not be set to line topics.'; + /** */ + changeBackgroundColor(color) { + const validateFunc = function (topic) { + return topic.getShapeType() != TopicShape.LINE; + }; + const validateError = 'Color can not be set to line topics.'; - var topicsIds = this.getModel().filterTopicsIds(validateFunc, validateError); - if (topicsIds.length > 0) { - this._actionDispatcher.changeBackgroundColorToTopic(topicsIds, color); - } - }, + const topicsIds = this.getModel().filterTopicsIds(validateFunc, validateError); + if (topicsIds.length > 0) { + this._actionDispatcher.changeBackgroundColorToTopic(topicsIds, color); + } + }, - /** */ - changeBorderColor: function (color) { - var validateFunc = function (topic) { - return topic.getShapeType() != TopicShape.LINE; - }; - var validateError = 'Color can not be set to line topics.'; - var topicsIds = this.getModel().filterTopicsIds(validateFunc, validateError); - if (topicsIds.length > 0) { - this._actionDispatcher.changeBorderColorToTopic(topicsIds, color); - } - }, + /** */ + changeBorderColor(color) { + const validateFunc = function (topic) { + return topic.getShapeType() != TopicShape.LINE; + }; + const validateError = 'Color can not be set to line topics.'; + const topicsIds = this.getModel().filterTopicsIds(validateFunc, validateError); + if (topicsIds.length > 0) { + this._actionDispatcher.changeBorderColorToTopic(topicsIds, color); + } + }, - /** */ - changeFontSize: function (size) { - var topicsIds = this.getModel().filterTopicsIds(); - if (topicsIds.length > 0) { - this._actionDispatcher.changeFontSizeToTopic(topicsIds, size); - } - }, + /** */ + changeFontSize(size) { + const topicsIds = this.getModel().filterTopicsIds(); + if (topicsIds.length > 0) { + this._actionDispatcher.changeFontSizeToTopic(topicsIds, size); + } + }, - /** */ - changeTopicShape: function (shape) { - var validateFunc = function (topic) { - return !( - topic.getType() == INodeModel.CENTRAL_TOPIC_TYPE && shape == TopicShape.LINE - ); - }; + /** */ + changeTopicShape(shape) { + const validateFunc = function (topic) { + return !( + topic.getType() == INodeModel.CENTRAL_TOPIC_TYPE && shape == TopicShape.LINE + ); + }; - var validateError = 'Central Topic shape can not be changed to line figure.'; - var topicsIds = this.getModel().filterTopicsIds(validateFunc, validateError); - if (topicsIds.length > 0) { - this._actionDispatcher.changeShapeTypeToTopic(topicsIds, shape); - } - }, + const validateError = 'Central Topic shape can not be changed to line figure.'; + const topicsIds = this.getModel().filterTopicsIds(validateFunc, validateError); + if (topicsIds.length > 0) { + this._actionDispatcher.changeShapeTypeToTopic(topicsIds, shape); + } + }, - /** */ - changeFontWeight: function () { - var topicsIds = this.getModel().filterTopicsIds(); - if (topicsIds.length > 0) { - this._actionDispatcher.changeFontWeightToTopic(topicsIds); - } - }, + /** */ + changeFontWeight() { + const topicsIds = this.getModel().filterTopicsIds(); + if (topicsIds.length > 0) { + this._actionDispatcher.changeFontWeightToTopic(topicsIds); + } + }, - /** */ - addIconType: function (iconType) { - var topicsIds = this.getModel().filterTopicsIds(); - if (topicsIds.length > 0) { - this._actionDispatcher.addFeatureToTopic(topicsIds[0], TopicFeature.Icon.id, { - id: iconType, - }); - } - }, + /** */ + addIconType(iconType) { + const topicsIds = this.getModel().filterTopicsIds(); + if (topicsIds.length > 0) { + this._actionDispatcher.addFeatureToTopic(topicsIds[0], TopicFeature.Icon.id, { + id: iconType, + }); + } + }, - /** + /** * lets the selected topic open the link editor where the user can define or modify an * existing link */ - addLink: function () { - var model = this.getModel(); - var topic = model.selectedTopic(); - if (topic) { - topic.showLinkEditor(); - this.onObjectFocusEvent(); - } - }, + addLink() { + const model = this.getModel(); + const topic = model.selectedTopic(); + if (topic) { + topic.showLinkEditor(); + this.onObjectFocusEvent(); + } + }, - /** */ - addNote: function () { - var model = this.getModel(); - var topic = model.selectedTopic(); - if (topic) { - topic.showNoteEditor(); - this.onObjectFocusEvent(); - } - }, + /** */ + addNote() { + const model = this.getModel(); + const topic = model.selectedTopic(); + if (topic) { + topic.showNoteEditor(); + this.onObjectFocusEvent(); + } + }, - /** + /** * @param {mindplot.Topic} node * sets the focus to the given node */ - goToNode: function (node) { - node.setOnFocus(true); - this.onObjectFocusEvent(node); - }, + goToNode(node) { + node.setOnFocus(true); + this.onObjectFocusEvent(node); + }, - /** @return {mindplot.Workspace} */ - getWorkSpace: function () { - return this._workspace; - }, - } + /** @return {mindplot.Workspace} */ + getWorkSpace() { + return this._workspace; + }, + }, ); export default Designer; diff --git a/packages/mindplot/lib/components/DesignerActionRunner.js b/packages/mindplot/lib/components/DesignerActionRunner.js index 3b5620a2..777e1737 100644 --- a/packages/mindplot/lib/components/DesignerActionRunner.js +++ b/packages/mindplot/lib/components/DesignerActionRunner.js @@ -19,40 +19,38 @@ const DesignerUndoManager = require('./DesignerUndoManager').default; const EventBus = require('./layout/EventBus').default; const DesignerActionRunner = new Class({ - initialize: function (commandContext, notifier) { - $assert(commandContext, "commandContext can not be null"); + initialize(commandContext, notifier) { + $assert(commandContext, 'commandContext can not be null'); - this._undoManager = new DesignerUndoManager(); - this._context = commandContext; - this._notifier = notifier; - }, + this._undoManager = new DesignerUndoManager(); + this._context = commandContext; + this._notifier = notifier; + }, - execute: function (command) { - $assert(command, "command can not be null"); - command.execute(this._context); - this._undoManager.enqueue(command); - this.fireChangeEvent(); - EventBus.instance.fireEvent(EventBus.events.DoLayout); + execute(command) { + $assert(command, 'command can not be null'); + command.execute(this._context); + this._undoManager.enqueue(command); + this.fireChangeEvent(); + EventBus.instance.fireEvent(EventBus.events.DoLayout); + }, - }, + undo() { + this._undoManager.execUndo(this._context); + this.fireChangeEvent(); + EventBus.instance.fireEvent(EventBus.events.DoLayout); + }, - undo: function () { - this._undoManager.execUndo(this._context); - this.fireChangeEvent(); - EventBus.instance.fireEvent(EventBus.events.DoLayout); - }, + redo() { + this._undoManager.execRedo(this._context); + this.fireChangeEvent(); + EventBus.instance.fireEvent(EventBus.events.DoLayout); + }, - redo: function () { - this._undoManager.execRedo(this._context); - this.fireChangeEvent(); - EventBus.instance.fireEvent(EventBus.events.DoLayout); - - }, - - fireChangeEvent: function () { - var event = this._undoManager.buildEvent(); - this._notifier.fireEvent("modelUpdate", event); - } + fireChangeEvent() { + const event = this._undoManager.buildEvent(); + this._notifier.fireEvent('modelUpdate', event); + }, }); export default DesignerActionRunner; diff --git a/packages/mindplot/lib/components/DesignerKeyboard.js b/packages/mindplot/lib/components/DesignerKeyboard.js index b59ef6d3..c7e85a92 100644 --- a/packages/mindplot/lib/components/DesignerKeyboard.js +++ b/packages/mindplot/lib/components/DesignerKeyboard.js @@ -18,383 +18,416 @@ const Keyboard = require('./Keyboard').default; const DesignerKeyboard = new Class({ - Extends: Keyboard, - Static:{ - register:function (designer) { - this._instance = new DesignerKeyboard(designer); - }, + Extends: Keyboard, + Static: { + register(designer) { + this._instance = new DesignerKeyboard(designer); + }, - getInstance:function () { - return this._instance; + getInstance() { + return this._instance; + }, + }, + + initialize(designer) { + $assert(designer, 'designer can not be null'); + this._registerEvents(designer); + }, + + _registerEvents(designer) { + // Try with the keyboard .. + const model = designer.getModel(); + this.addShortcut( + ['backspace'], (event) => { + event.preventDefault(); + event.stopPropagation(); + designer.deleteSelectedEntities(); + }, + ); + this.addShortcut( + ['space'], () => { + designer.shrinkSelectedBranch(); + }, + ); + this.addShortcut( + ['f2'], (event) => { + event.stopPropagation(); + event.preventDefault(); + const node = model.selectedTopic(); + if (node) { + node.showTextEditor(); } - }, + }, + ); + this.addShortcut( + ['del'], (event) => { + designer.deleteSelectedEntities(); + event.preventDefault(); + event.stopPropagation(); + }, + ); + this.addShortcut( + ['enter'], () => { + designer.createSiblingForSelectedNode(); + }, + ); + this.addShortcut( + ['insert'], (event) => { + designer.createChildForSelectedNode(); + event.preventDefault(); + event.stopPropagation(); + }, + ); + this.addShortcut( + ['tab'], (event) => { + designer.createChildForSelectedNode(); + event.preventDefault(); + event.stopPropagation(); + }, + ); + this.addShortcut( + ['meta+enter'], (event) => { + event.preventDefault(); + event.stopPropagation(); + designer.createChildForSelectedNode(); + }, + ); + this.addShortcut( + ['ctrl+z', 'meta+z'], (event) => { + event.preventDefault(event); + event.stopPropagation(); + designer.undo(); + }, + ); + this.addShortcut( + ['ctrl+c', 'meta+c'], (event) => { + event.preventDefault(event); + event.stopPropagation(); + designer.copyToClipboard(); + }, + ); + this.addShortcut( + ['ctrl+v', 'meta+v'], (event) => { + event.preventDefault(event); + event.stopPropagation(); + designer.pasteClipboard(); + }, + ); + this.addShortcut( + ['ctrl+shift+z', 'meta+shift+z', 'ctrl+y', 'meta+y'], (event) => { + event.preventDefault(); + event.stopPropagation(); + designer.redo(); + }, + ); + this.addShortcut( + ['ctrl+a', 'meta+a'], (event) => { + event.preventDefault(); + event.stopPropagation(); + designer.selectAll(); + }, + ); + this.addShortcut( + ['ctrl+b', 'meta+b'], (event) => { + event.preventDefault(); + event.stopPropagation(); - initialize:function (designer) { - $assert(designer, "designer can not be null"); - this._registerEvents(designer); - }, + designer.changeFontWeight(); + }, + ); + this.addShortcut( + ['ctrl+s', 'meta+s'], (event) => { + event.preventDefault(); + event.stopPropagation(); + $(document).find('#save').trigger('click'); + }, + ); + this.addShortcut( + ['ctrl+i', 'meta+i'], (event) => { + event.preventDefault(); + event.stopPropagation(); - _registerEvents:function (designer) { + designer.changeFontStyle(); + }, + ); + this.addShortcut( + ['ctrl+shift+a', 'meta+shift+a'], (event) => { + event.preventDefault(); + event.stopPropagation(); - // Try with the keyboard .. - var model = designer.getModel(); - this.addShortcut( - ['backspace'], function (event) { - event.preventDefault(); - event.stopPropagation(); - designer.deleteSelectedEntities(); - } - ); - this.addShortcut( - ['space'], function() { - designer.shrinkSelectedBranch(); - } - ); - this.addShortcut( - ['f2'],function(event) { - event.stopPropagation(); - event.preventDefault(); - var node = model.selectedTopic(); - if (node) { - node.showTextEditor(); - } - } - ); - this.addShortcut( - ['del'], function(event) { - designer.deleteSelectedEntities(); - event.preventDefault(); - event.stopPropagation(); - } - ); - this.addShortcut( - ['enter'], function() { - designer.createSiblingForSelectedNode(); - } - ); - this.addShortcut( - ['insert'], function(event) { - designer.createChildForSelectedNode(); - event.preventDefault(); - event.stopPropagation(); - } - ); - this.addShortcut( - ['tab'], function(event) { - designer.createChildForSelectedNode(); - event.preventDefault(); - event.stopPropagation(); - } - ); - this.addShortcut( - ['meta+enter'], function(event) { - event.preventDefault(); - event.stopPropagation(); - designer.createChildForSelectedNode(); - } - ); - this.addShortcut( - ['ctrl+z', 'meta+z'], function(event) { - event.preventDefault(event); - event.stopPropagation(); - designer.undo(); - } - ); - this.addShortcut( - ['ctrl+c', 'meta+c'], function (event) { - event.preventDefault(event); - event.stopPropagation(); - designer.copyToClipboard(); - } - ); - this.addShortcut( - ['ctrl+v', 'meta+v'], function (event) { - event.preventDefault(event); - event.stopPropagation(); - designer.pasteClipboard(); - } - ); - this.addShortcut( - ['ctrl+shift+z', 'meta+shift+z', 'ctrl+y', 'meta+y'], function (event) { - event.preventDefault(); - event.stopPropagation(); - designer.redo(); - } - ); - this.addShortcut( - ['ctrl+a', 'meta+a'], function (event) { - event.preventDefault(); - event.stopPropagation(); - designer.selectAll(); - } - ); - this.addShortcut( - ['ctrl+b', 'meta+b'], function (event) { - event.preventDefault(); - event.stopPropagation(); - - designer.changeFontWeight(); - } - ); - this.addShortcut( - ['ctrl+s', 'meta+s'], function (event) { - event.preventDefault(); - event.stopPropagation(); - $(document).find('#save').trigger('click'); - } - ); - this.addShortcut( - ['ctrl+i', 'meta+i'], function (event) { - event.preventDefault(); - event.stopPropagation(); - - designer.changeFontStyle(); - } - ); - this.addShortcut( - ['ctrl+shift+a', 'meta+shift+a'], function (event) { - event.preventDefault(); - event.stopPropagation(); - - designer.deselectAll(); - } - ); - this.addShortcut( - ['meta+=', 'ctrl+='], function (event) { - event.preventDefault(); - event.stopPropagation(); - - designer.zoomIn(); - } - ); - this.addShortcut( - ['meta+-', 'ctrl+-'], function (event) { - event.preventDefault(); - event.stopPropagation(); - - designer.zoomOut(); - } - ); - var me = this; - this.addShortcut( - 'right', function (event) { - var node = model.selectedTopic(); - if (node) { - if (node.isCentralTopic()) { - me._goToSideChild(designer, node, 'RIGHT'); - } - else { - if (node.getPosition().x < 0) { - me._goToParent(designer, node); - } - else if (!node.areChildrenShrunken()) { - me._goToChild(designer, node); - } - } - } else { - var centralTopic = model.getCentralTopic(); - me._goToNode(designer, centralTopic); - } - event.preventDefault(); - event.stopPropagation(); - } - ); - this.addShortcut( - 'left', function (event) { - var node = model.selectedTopic(); - if (node) { - if (node.isCentralTopic()) { - me._goToSideChild(designer, node, 'LEFT'); - } - else { - if (node.getPosition().x > 0) { - me._goToParent(designer, node); - } - else if (!node.areChildrenShrunken()) { - me._goToChild(designer, node); - } - } - } else { - var centralTopic = model.getCentralTopic(); - me._goToNode(designer, centralTopic); - } - event.preventDefault(); - event.stopPropagation(); - } - ); - this.addShortcut( - 'up', function (event) { - var node = model.selectedTopic(); - if (node) { - if (!node.isCentralTopic()) { - me._goToBrother(designer, node, 'UP'); - } - } else { - var centralTopic = model.getCentralTopic(); - me._goToNode(designer, centralTopic); - } - event.preventDefault(); - event.stopPropagation(); - } - ); - this.addShortcut( - 'down', function (event) { - var node = model.selectedTopic(); - if (node) { - if (!node.isCentralTopic()) { - me._goToBrother(designer, node, 'DOWN'); - } - } else { - var centralTopic = model.getCentralTopic(); - me._goToNode(designer, centralTopic); - } - event.preventDefault(); - event.stopPropagation(); - } - ); - var excludes = ['esc', 'escape', 'f1', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12']; - - $(document).on('keypress', function (event) { - var keyCode; - // Firefox doesn't skip special keys for keypress event... - if (event.key && excludes.contains(event.key.toLowerCase())) { - return; - } - // Sometimes Firefox doesn't contain keyCode value - if (event.key && event.keyCode == 0) { - keyCode = event.charCode; - } else { - keyCode = event.keyCode; - } - - var specialKey = jQuery.hotkeys.specialKeys[keyCode]; - if (["enter", "capslock"].indexOf(specialKey) == -1 && !jQuery.hotkeys.shiftNums[keyCode]) { - var nodes = designer.getModel().filterSelectedTopics(); - if (nodes.length > 0) { - - // If a modifier is press, the key selected must be ignored. - var pressKey = String.fromCharCode(keyCode); - if (event.ctrlKey || event.altKey || event.metaKey) { - return; - } - nodes[0].showTextEditor(pressKey); - event.stopPropagation(); - } - } - - }); - - }, - - _goToBrother:function (designer, node, direction) { - var parent = node.getParent(); - if (parent) { - var brothers = parent.getChildren(); - - var target = node; - var y = node.getPosition().y; - var x = node.getPosition().x; - var dist = null; - for (var i = 0; i < brothers.length; i++) { - var sameSide = (x * brothers[i].getPosition().x) >= 0; - if (brothers[i] != node && sameSide) { - var brother = brothers[i]; - var brotherY = brother.getPosition().y; - if (direction == "DOWN" && brotherY > y) { - var distancia = y - brotherY; - if (distancia < 0) { - distancia = distancia * (-1); - } - if (dist == null || dist > distancia) { - dist = distancia; - target = brothers[i]; - } - } - else if (direction == "UP" && brotherY < y) { - var distance = y - brotherY; - if (distance < 0) { - distance = distance * (-1); - } - if (dist == null || dist > distance) { - dist = distance; - target = brothers[i]; - } - } - } - } - this._goToNode(designer, target); - } - }, - - - _goToSideChild:function (designer, node, side) { - var children = node.getChildren(); - if (children.length > 0) { - var target = children[0]; - var top = null; - for (var i = 0; i < children.length; i++) { - var child = children[i]; - var childY = child.getPosition().y; - if (side == 'LEFT' && child.getPosition().x < 0) { - if (top == null || childY < top) { - target = child; - top = childY; - } - } - if (side == 'RIGHT' && child.getPosition().x > 0) { - if (top == null || childY < top) { - target = child; - top = childY; - } - } - } - - this._goToNode(designer, target); - } - }, - - _goToParent:function (designer, node) { - var parent = node.getParent(); - if (parent) { - this._goToNode(designer, parent); - } - }, - - _goToChild:function (designer, node) { - var children = node.getChildren(); - if (children.length > 0) { - var target = children[0]; - var top = target.getPosition().y; - for (var i = 0; i < children.length; i++) { - var child = children[i]; - if (child.getPosition().y < top) { - top = child.getPosition().y; - target = child; - } - } - this._goToNode(designer, target); - } - }, - - _goToNode:function (designer, node) { - // First deselect all the nodes ... designer.deselectAll(); + }, + ); + this.addShortcut( + ['meta+=', 'ctrl+='], (event) => { + event.preventDefault(); + event.stopPropagation(); - // Give focus to the selected node.... - node.setOnFocus(true); + designer.zoomIn(); + }, + ); + this.addShortcut( + ['meta+-', 'ctrl+-'], (event) => { + event.preventDefault(); + event.stopPropagation(); + + designer.zoomOut(); + }, + ); + const me = this; + this.addShortcut( + 'right', (event) => { + const node = model.selectedTopic(); + if (node) { + if (node.isCentralTopic()) { + me._goToSideChild(designer, node, 'RIGHT'); + } else if (node.getPosition().x < 0) { + me._goToParent(designer, node); + } else if (!node.areChildrenShrunken()) { + me._goToChild(designer, node); + } + } else { + const centralTopic = model.getCentralTopic(); + me._goToNode(designer, centralTopic); + } + event.preventDefault(); + event.stopPropagation(); + }, + ); + this.addShortcut( + 'left', (event) => { + const node = model.selectedTopic(); + if (node) { + if (node.isCentralTopic()) { + me._goToSideChild(designer, node, 'LEFT'); + } else if (node.getPosition().x > 0) { + me._goToParent(designer, node); + } else if (!node.areChildrenShrunken()) { + me._goToChild(designer, node); + } + } else { + const centralTopic = model.getCentralTopic(); + me._goToNode(designer, centralTopic); + } + event.preventDefault(); + event.stopPropagation(); + }, + ); + this.addShortcut( + 'up', (event) => { + const node = model.selectedTopic(); + if (node) { + if (!node.isCentralTopic()) { + me._goToBrother(designer, node, 'UP'); + } + } else { + const centralTopic = model.getCentralTopic(); + me._goToNode(designer, centralTopic); + } + event.preventDefault(); + event.stopPropagation(); + }, + ); + this.addShortcut( + 'down', (event) => { + const node = model.selectedTopic(); + if (node) { + if (!node.isCentralTopic()) { + me._goToBrother(designer, node, 'DOWN'); + } + } else { + const centralTopic = model.getCentralTopic(); + me._goToNode(designer, centralTopic); + } + event.preventDefault(); + event.stopPropagation(); + }, + ); + const excludes = ['esc', 'escape', 'f1', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12']; + + $(document).on('keypress', (event) => { + let keyCode; + // Firefox doesn't skip special keys for keypress event... + if (event.key && excludes.contains(event.key.toLowerCase())) { + return; + } + // Sometimes Firefox doesn't contain keyCode value + if (event.key && event.keyCode == 0) { + keyCode = event.charCode; + } else { + keyCode = event.keyCode; + } + + const specialKey = jQuery.hotkeys.specialKeys[keyCode]; + if (['enter', 'capslock'].indexOf(specialKey) == -1 && !jQuery.hotkeys.shiftNums[keyCode]) { + const nodes = designer.getModel().filterSelectedTopics(); + if (nodes.length > 0) { + // If a modifier is press, the key selected must be ignored. + const pressKey = String.fromCharCode(keyCode); + if (event.ctrlKey || event.altKey || event.metaKey) { + return; + } + nodes[0].showTextEditor(pressKey); + event.stopPropagation(); + } + } + }); + }, + + _goToBrother(designer, node, direction) { + const parent = node.getParent(); + if (parent) { + const brothers = parent.getChildren(); + + let target = node; + const { y } = node.getPosition(); + const { x } = node.getPosition(); + let dist = null; + for (let i = 0; i < brothers.length; i++) { + const sameSide = (x * brothers[i].getPosition().x) >= 0; + if (brothers[i] != node && sameSide) { + const brother = brothers[i]; + const brotherY = brother.getPosition().y; + if (direction == 'DOWN' && brotherY > y) { + let distancia = y - brotherY; + if (distancia < 0) { + distancia *= (-1); + } + if (dist == null || dist > distancia) { + dist = distancia; + target = brothers[i]; + } + } else if (direction == 'UP' && brotherY < y) { + let distance = y - brotherY; + if (distance < 0) { + distance *= (-1); + } + if (dist == null || dist > distance) { + dist = distance; + target = brothers[i]; + } + } + } + } + this._goToNode(designer, target); } + }, + + _goToSideChild(designer, node, side) { + const children = node.getChildren(); + if (children.length > 0) { + let target = children[0]; + let top = null; + for (let i = 0; i < children.length; i++) { + const child = children[i]; + const childY = child.getPosition().y; + if (side == 'LEFT' && child.getPosition().x < 0) { + if (top == null || childY < top) { + target = child; + top = childY; + } + } + if (side == 'RIGHT' && child.getPosition().x > 0) { + if (top == null || childY < top) { + target = child; + top = childY; + } + } + } + + this._goToNode(designer, target); + } + }, + + _goToParent(designer, node) { + const parent = node.getParent(); + if (parent) { + this._goToNode(designer, parent); + } + }, + + _goToChild(designer, node) { + const children = node.getChildren(); + if (children.length > 0) { + let target = children[0]; + let top = target.getPosition().y; + for (let i = 0; i < children.length; i++) { + const child = children[i]; + if (child.getPosition().y < top) { + top = child.getPosition().y; + target = child; + } + } + this._goToNode(designer, target); + } + }, + + _goToNode(designer, node) { + // First deselect all the nodes ... + designer.deselectAll(); + + // Give focus to the selected node.... + node.setOnFocus(true); + }, }); DesignerKeyboard.specialKeys = { - 8: "backspace", 9: "tab", 10: "return", 13: "enter", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause", - 20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home", - 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del", - 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7", - 104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/", - 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8", - 120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 186: ";", 191: "/", - 220: "\\", 222: "'", 224: "meta" + 8: 'backspace', + 9: 'tab', + 10: 'return', + 13: 'enter', + 16: 'shift', + 17: 'ctrl', + 18: 'alt', + 19: 'pause', + 20: 'capslock', + 27: 'esc', + 32: 'space', + 33: 'pageup', + 34: 'pagedown', + 35: 'end', + 36: 'home', + 37: 'left', + 38: 'up', + 39: 'right', + 40: 'down', + 45: 'insert', + 46: 'del', + 96: '0', + 97: '1', + 98: '2', + 99: '3', + 100: '4', + 101: '5', + 102: '6', + 103: '7', + 104: '8', + 105: '9', + 106: '*', + 107: '+', + 109: '-', + 110: '.', + 111: '/', + 112: 'f1', + 113: 'f2', + 114: 'f3', + 115: 'f4', + 116: 'f5', + 117: 'f6', + 118: 'f7', + 119: 'f8', + 120: 'f9', + 121: 'f10', + 122: 'f11', + 123: 'f12', + 144: 'numlock', + 145: 'scroll', + 186: ';', + 191: '/', + 220: '\\', + 222: "'", + 224: 'meta', }; export default DesignerKeyboard; diff --git a/packages/mindplot/lib/components/DesignerModel.js b/packages/mindplot/lib/components/DesignerModel.js index 5ce65710..994214a0 100644 --- a/packages/mindplot/lib/components/DesignerModel.js +++ b/packages/mindplot/lib/components/DesignerModel.js @@ -18,174 +18,172 @@ const Events = require('./Events').default; const DesignerModel = new Class(/** @lends DesignerModel */{ - Implements:[Events], - /** + Implements: [Events], + /** * @implements {mindplot.Events} * @constructs - * @param {{readOnly: Boolean, zoom: Number, saveOnLoad: Boolean, size: {width: Number, - * height: Number}, viewPort: {width: Number, height: Number}, container: String, + * @param {{readOnly: Boolean, zoom: Number, saveOnLoad: Boolean, size: {width: Number, + * height: Number}, viewPort: {width: Number, height: Number}, container: String, * persistenceManager: String, mapId: String, locale: String}} options - * options loaded from json config + * options loaded from json config * @see {@link ConfigParameters.md} * @see {@link editor.html} */ - initialize:function (options) { - this._zoom = options.zoom; - this._topics = []; - this._relationships = []; - }, + initialize(options) { + this._zoom = options.zoom; + this._topics = []; + this._relationships = []; + }, - /** @return {Number} zoom between 0.3 (largest text) and 1.9 */ - getZoom:function () { - return this._zoom; - }, + /** @return {Number} zoom between 0.3 (largest text) and 1.9 */ + getZoom() { + return this._zoom; + }, - /** @param {Number} zoom number between 0.3 and 1.9 to set the zoom to */ - setZoom:function (zoom) { - this._zoom = zoom; - }, + /** @param {Number} zoom number between 0.3 and 1.9 to set the zoom to */ + setZoom(zoom) { + this._zoom = zoom; + }, - /** @return {@link mindplot.Topic[]} all topics */ - getTopics:function () { - return this._topics; - }, + /** @return {@link mindplot.Topic[]} all topics */ + getTopics() { + return this._topics; + }, - /** @return {mindplot.Relationship[]} all relationships */ - getRelationships:function () { - return this._relationships; - }, + /** @return {mindplot.Relationship[]} all relationships */ + getRelationships() { + return this._relationships; + }, - /** @return {mindplot.CentralTopic} the central topic */ - getCentralTopic:function () { - var topics = this.getTopics(); - return topics[0]; - }, + /** @return {mindplot.CentralTopic} the central topic */ + getCentralTopic() { + const topics = this.getTopics(); + return topics[0]; + }, - /** @return {mindplot.Topic[]} selected topics */ - filterSelectedTopics:function () { - var result = []; - for (var i = 0; i < this._topics.length; i++) { - if (this._topics[i].isOnFocus()) { - result.push(this._topics[i]); - } - } - return result; - }, + /** @return {mindplot.Topic[]} selected topics */ + filterSelectedTopics() { + const result = []; + for (let i = 0; i < this._topics.length; i++) { + if (this._topics[i].isOnFocus()) { + result.push(this._topics[i]); + } + } + return result; + }, - /** + /** * @return {mindplot.Relationship[]} selected relationships */ - filterSelectedRelationships:function () { - var result = []; - for (var i = 0; i < this._relationships.length; i++) { - if (this._relationships[i].isOnFocus()) { - result.push(this._relationships[i]); - } - } - return result; - }, + filterSelectedRelationships() { + const result = []; + for (let i = 0; i < this._relationships.length; i++) { + if (this._relationships[i].isOnFocus()) { + result.push(this._relationships[i]); + } + } + return result; + }, - /** + /** * @return {Array.} all topics and relationships */ - getEntities:function () { - var result = [].append(this._topics); - result.append(this._relationships); - return result; - }, + getEntities() { + const result = [].append(this._topics); + result.append(this._relationships); + return result; + }, - /** + /** * removes occurrences of the given topic from the topic array * @param {mindplot.Topic} topic the topic to remove */ - removeTopic:function (topic) { - $assert(topic, "topic can not be null"); - this._topics.erase(topic); - }, + removeTopic(topic) { + $assert(topic, 'topic can not be null'); + this._topics.erase(topic); + }, - /** + /** * removes occurrences of the given relationship from the relationship array * @param {mindplot.Relationship} rel the relationship to remove */ - removeRelationship:function (rel) { - $assert(rel, "rel can not be null"); - this._relationships.erase(rel); - }, + removeRelationship(rel) { + $assert(rel, 'rel can not be null'); + this._relationships.erase(rel); + }, - /** + /** * adds the given topic to the topic array * @param {mindplot.Topic} topic the topic to add * @throws will throw an error if topic is null or undefined * @throws will throw an error if the topic's id is not a number */ - addTopic:function (topic) { - $assert(topic, "topic can not be null"); - $assert(typeof topic.getId() == "number", "id is not a number:" + topic.getId()); - this._topics.push(topic); - }, + addTopic(topic) { + $assert(topic, 'topic can not be null'); + $assert(typeof topic.getId() === 'number', `id is not a number:${topic.getId()}`); + this._topics.push(topic); + }, - /** + /** * adds the given relationship to the relationship array * @param {mindplot.Relationship} rel the relationship to add * @throws will throw an error if rel is null or undefined */ - addRelationship:function (rel) { - $assert(rel, "rel can not be null"); - this._relationships.push(rel); - }, + addRelationship(rel) { + $assert(rel, 'rel can not be null'); + this._relationships.push(rel); + }, - /** + /** * @param {Function=} validate a function to validate nodes * @param {String=} errorMsg an error message to display if the validation fails * @return {String} returns an array of the selected (and, if applicable, valid) topics' ids */ - filterTopicsIds:function (validate, errorMsg) { - var result = []; - var topics = this.filterSelectedTopics(); + filterTopicsIds(validate, errorMsg) { + const result = []; + const topics = this.filterSelectedTopics(); + let isValid = true; + for (let i = 0; i < topics.length; i++) { + const selectedNode = topics[i]; + if ($defined(validate)) { + isValid = validate(selectedNode); + } - var isValid = true; - for (var i = 0; i < topics.length; i++) { - var selectedNode = topics[i]; - if ($defined(validate)) { - isValid = validate(selectedNode); - } + // Add node only if it's valid. + if (isValid) { + result.push(selectedNode.getId()); + } else { + $notify(errorMsg); + } + } + return result; + }, - // Add node only if it's valid. - if (isValid) { - result.push(selectedNode.getId()); - } else { - $notify(errorMsg); - } - } - return result; - }, - - /** - * @return {mindplot.Topic} the first selected topic if one or more are found by the + /** + * @return {mindplot.Topic} the first selected topic if one or more are found by the * filterSelectedTopics function, null otherwise */ - selectedTopic:function () { - var topics = this.filterSelectedTopics(); - return (topics.length > 0) ? topics[0] : null; - }, + selectedTopic() { + const topics = this.filterSelectedTopics(); + return (topics.length > 0) ? topics[0] : null; + }, - /** + /** * @param {String} id the id of the topic to be retrieved * @return {mindplot.Topic} the topic with the respective id */ - findTopicById:function (id) { - var result = null; - for (var i = 0; i < this._topics.length; i++) { - var topic = this._topics[i]; - if (topic.getId() == id) { - result = topic; - break; - } - } - return result; - + findTopicById(id) { + let result = null; + for (let i = 0; i < this._topics.length; i++) { + const topic = this._topics[i]; + if (topic.getId() == id) { + result = topic; + break; + } } + return result; + }, }); export default DesignerModel; diff --git a/packages/mindplot/lib/components/DesignerUndoManager.js b/packages/mindplot/lib/components/DesignerUndoManager.js index 63fa4feb..15f06754 100644 --- a/packages/mindplot/lib/components/DesignerUndoManager.js +++ b/packages/mindplot/lib/components/DesignerUndoManager.js @@ -17,69 +17,69 @@ */ const DesignerUndoManager = new Class({ - initialize: function(fireChange) { - this._undoQueue = []; - this._redoQueue = []; - this._baseId = 0; - }, + initialize(fireChange) { + this._undoQueue = []; + this._redoQueue = []; + this._baseId = 0; + }, - enqueue:function(command) { - $assert(command, "Command can not be null"); - var length = this._undoQueue.length; - if (command.discardDuplicated && length > 0) { - // Skip duplicated events ... - var lastItem = this._undoQueue[length - 1]; - if (lastItem.discardDuplicated != command.discardDuplicated) { - this._undoQueue.push(command); - } - } else { - this._undoQueue.push(command); - } - this._redoQueue = []; - }, - - execUndo: function(commandContext) { - if (this._undoQueue.length > 0) { - var command = this._undoQueue.pop(); - this._redoQueue.push(command); - - command.undoExecute(commandContext); - } - }, - - execRedo: function(commandContext) { - if (this._redoQueue.length > 0) { - var command = this._redoQueue.pop(); - this._undoQueue.push(command); - command.execute(commandContext); - } - }, - - buildEvent: function() { - return {undoSteps: this._undoQueue.length, redoSteps:this._redoQueue.length}; - }, - - markAsChangeBase: function() { - var undoLength = this._undoQueue.length; - if (undoLength > 0) { - var command = this._undoQueue[undoLength - 1]; - this._baseId = command.getId(); - } else { - this._baseId = 0; - } - }, - - hasBeenChanged: function() { - var result = true; - var undoLength= this._undoQueue.length; - if (undoLength == 0 && this._baseId == 0) { - result = false; - } else if (undoLength > 0) { - var command = this._undoQueue[undoLength - 1]; - result = (this._baseId != command.getId()); - } - return result; + enqueue(command) { + $assert(command, 'Command can not be null'); + const { length } = this._undoQueue; + if (command.discardDuplicated && length > 0) { + // Skip duplicated events ... + const lastItem = this._undoQueue[length - 1]; + if (lastItem.discardDuplicated != command.discardDuplicated) { + this._undoQueue.push(command); + } + } else { + this._undoQueue.push(command); } + this._redoQueue = []; + }, + + execUndo(commandContext) { + if (this._undoQueue.length > 0) { + const command = this._undoQueue.pop(); + this._redoQueue.push(command); + + command.undoExecute(commandContext); + } + }, + + execRedo(commandContext) { + if (this._redoQueue.length > 0) { + const command = this._redoQueue.pop(); + this._undoQueue.push(command); + command.execute(commandContext); + } + }, + + buildEvent() { + return { undoSteps: this._undoQueue.length, redoSteps: this._redoQueue.length }; + }, + + markAsChangeBase() { + const undoLength = this._undoQueue.length; + if (undoLength > 0) { + const command = this._undoQueue[undoLength - 1]; + this._baseId = command.getId(); + } else { + this._baseId = 0; + } + }, + + hasBeenChanged() { + let result = true; + const undoLength = this._undoQueue.length; + if (undoLength == 0 && this._baseId == 0) { + result = false; + } else if (undoLength > 0) { + const command = this._undoQueue[undoLength - 1]; + result = (this._baseId != command.getId()); + } + return result; + }, }); export default DesignerUndoManager; diff --git a/packages/mindplot/lib/components/DragConnector.js b/packages/mindplot/lib/components/DragConnector.js index 4505e052..da539906 100644 --- a/packages/mindplot/lib/components/DragConnector.js +++ b/packages/mindplot/lib/components/DragConnector.js @@ -17,99 +17,94 @@ */ const DragConnector = new Class({ - initialize:function (designerModel, workspace) { - $assert(designerModel, 'designerModel can not be null'); - $assert(workspace, 'workspace can not be null'); + initialize(designerModel, workspace) { + $assert(designerModel, 'designerModel can not be null'); + $assert(workspace, 'workspace can not be null'); - // this._layoutManager = layoutManager; - this._designerModel = designerModel; - this._workspace = workspace; - }, + // this._layoutManager = layoutManager; + this._designerModel = designerModel; + this._workspace = workspace; + }, - checkConnection:function (dragTopic) { - var topics = this._designerModel.getTopics(); + checkConnection(dragTopic) { + const topics = this._designerModel.getTopics(); - // Must be disconnected from their current connection ?. - var candidates = this._searchConnectionCandidates(dragTopic); - var currentConnection = dragTopic.getConnectedToTopic(); - - - if (currentConnection && (candidates.length == 0 || candidates[0] != currentConnection)) { - dragTopic.disconnect(this._workspace); - } - - // Finally, connect nodes ... - if (!dragTopic.isConnected() && candidates.length > 0) { - dragTopic.connectTo(candidates[0]); - } - }, - - _searchConnectionCandidates:function (dragTopic) { - var topics = this._designerModel.getTopics(); - var draggedNode = dragTopic.getDraggedTopic(); - - // Drag node connects to the border ... - var dragTopicWidth = dragTopic.getSize ? dragTopic.getSize().width : 0; // Hack... - var xMouseGap = dragTopic.getPosition().x > 0 ? 0 : dragTopicWidth; - var sPos = {x:dragTopic.getPosition().x - xMouseGap, y:dragTopic.getPosition().y}; - - // Perform a initial filter to discard topics: - // - Exclude dragged topic - // - Exclude dragTopic pivot - // - Nodes that are collapsed - // - It's not part of the branch dragged itself - topics = topics.filter(function (topic) { - var result = draggedNode != topic; - result = result && topic != draggedNode; - result = result && !topic.areChildrenShrunken() && !topic.isCollapsed(); - result = result && !draggedNode.isChildTopic(topic); - return result; - }); - - // Filter all the nodes that are outside the vertical boundary: - // * The node is to out of the x scope - // * The x distance greater the vertical tolerated distance - topics = topics.filter(function (topic) { - var tpos = topic.getPosition(); - // Center topic has different alignment than the rest of the nodes. That's why i need to divide it by two... - var txborder = tpos.x + (topic.getSize().width / 2) * Math.sign(sPos.x); - var distance = (sPos.x - txborder) * Math.sign(sPos.x); - return distance > 0 && (distance < DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE); - - }); - - // Assign a priority based on the distance: - // - Alignment with the targetNode - // - Vertical distance - // - Horizontal proximity - // - It's already connected. - var currentConnection = dragTopic.getConnectedToTopic(); - var me = this; - topics = topics.sort(function (a, b) { - var aPos = a.getPosition(); - var bPos = b.getPosition(); - - var av = me._isVerticallyAligned(a.getSize(), aPos, sPos); - var bv = me._isVerticallyAligned(b.getSize(), bPos, sPos); - return me._proximityWeight(av, a, sPos, currentConnection) - me._proximityWeight(bv, b, sPos, currentConnection); - - }); - return topics; - }, - - _proximityWeight:function (isAligned, target, sPos, currentConnection) { - var tPos = target.getPosition(); - return (isAligned ? 0 : 200 ) + Math.abs(tPos.x - sPos.x) + Math.abs(tPos.y - sPos.y) + (currentConnection == target ? 0 : 100); - }, - - _isVerticallyAligned:function (targetSize, targetPosition, sourcePosition) { - - return Math.abs(sourcePosition.y - targetPosition.y) < targetSize.height / 2; + // Must be disconnected from their current connection ?. + const candidates = this._searchConnectionCandidates(dragTopic); + const currentConnection = dragTopic.getConnectedToTopic(); + if (currentConnection && (candidates.length == 0 || candidates[0] != currentConnection)) { + dragTopic.disconnect(this._workspace); } + // Finally, connect nodes ... + if (!dragTopic.isConnected() && candidates.length > 0) { + dragTopic.connectTo(candidates[0]); + } + }, + + _searchConnectionCandidates(dragTopic) { + let topics = this._designerModel.getTopics(); + const draggedNode = dragTopic.getDraggedTopic(); + + // Drag node connects to the border ... + const dragTopicWidth = dragTopic.getSize ? dragTopic.getSize().width : 0; // Hack... + const xMouseGap = dragTopic.getPosition().x > 0 ? 0 : dragTopicWidth; + const sPos = { x: dragTopic.getPosition().x - xMouseGap, y: dragTopic.getPosition().y }; + + // Perform a initial filter to discard topics: + // - Exclude dragged topic + // - Exclude dragTopic pivot + // - Nodes that are collapsed + // - It's not part of the branch dragged itself + topics = topics.filter((topic) => { + let result = draggedNode != topic; + result = result && topic != draggedNode; + result = result && !topic.areChildrenShrunken() && !topic.isCollapsed(); + result = result && !draggedNode.isChildTopic(topic); + return result; + }); + + // Filter all the nodes that are outside the vertical boundary: + // * The node is to out of the x scope + // * The x distance greater the vertical tolerated distance + topics = topics.filter((topic) => { + const tpos = topic.getPosition(); + // Center topic has different alignment than the rest of the nodes. That's why i need to divide it by two... + const txborder = tpos.x + (topic.getSize().width / 2) * Math.sign(sPos.x); + const distance = (sPos.x - txborder) * Math.sign(sPos.x); + return distance > 0 && (distance < DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE); + }); + + // Assign a priority based on the distance: + // - Alignment with the targetNode + // - Vertical distance + // - Horizontal proximity + // - It's already connected. + const currentConnection = dragTopic.getConnectedToTopic(); + const me = this; + topics = topics.sort((a, b) => { + const aPos = a.getPosition(); + const bPos = b.getPosition(); + + const av = me._isVerticallyAligned(a.getSize(), aPos, sPos); + const bv = me._isVerticallyAligned(b.getSize(), bPos, sPos); + return me._proximityWeight(av, a, sPos, currentConnection) - me._proximityWeight(bv, b, sPos, currentConnection); + }); + return topics; + }, + + _proximityWeight(isAligned, target, sPos, currentConnection) { + const tPos = target.getPosition(); + return (isAligned ? 0 : 200) + Math.abs(tPos.x - sPos.x) + Math.abs(tPos.y - sPos.y) + (currentConnection == target ? 0 : 100); + }, + + _isVerticallyAligned(targetSize, targetPosition, sourcePosition) { + return Math.abs(sourcePosition.y - targetPosition.y) < targetSize.height / 2; + }, + }); DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE = 80; -export default DragConnector +export default DragConnector; diff --git a/packages/mindplot/lib/components/DragManager.js b/packages/mindplot/lib/components/DragManager.js index 91ba6566..6c855ed2 100644 --- a/packages/mindplot/lib/components/DragManager.js +++ b/packages/mindplot/lib/components/DragManager.js @@ -1,151 +1,146 @@ -/* - * Copyright [2015] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -const DragTopic = require('./DragTopic').default; - -const DragManager = new Class({ - initialize:function(workspace, eventDispatcher) { - this._workspace = workspace; - this._designerModel = workspace; - this._listeners = {}; - this._isDragInProcess = false; - this._eventDispatcher = eventDispatcher; - DragTopic.init(this._workspace); - }, - - add : function(node) { - // Add behaviour ... - var workspace = this._workspace; - var screen = workspace.getScreenManager(); - var dragManager = this; - var me = this; - var mouseDownListener = function(event) { - if (workspace.isWorkspaceEventsEnabled()) { - // Disable double drag... - workspace.enableWorkspaceEvents(false); - - // Set initial position. - var layoutManager = me._eventDispatcher.getLayoutManager(); - var dragNode = node.createDragNode(layoutManager); - - // Register mouse move listener ... - var mouseMoveListener = dragManager._buildMouseMoveListener(workspace, dragNode, dragManager); - screen.addEvent('mousemove', mouseMoveListener); - - // Register mouse up listeners ... - var mouseUpListener = dragManager._buildMouseUpListener(workspace, node, dragNode, dragManager); - screen.addEvent('mouseup', mouseUpListener); - - // Change cursor. - window.document.body.style.cursor = 'move'; - } - }; - node.addEvent('mousedown', mouseDownListener); - }, - - remove : function(node) { - var nodes = this._topics; - var contained = false; - var index = -1; - for (var i = 0; i < nodes.length; i++) { - if (nodes[i] == node) { - contained = true; - index = i; - } - } - }, - - _buildMouseMoveListener : function(workspace, dragNode, dragManager) { - var screen = workspace.getScreenManager(); - var me = this; - var result = function(event) { - - if (!me._isDragInProcess) { - // Execute Listeners .. - var startDragListener = dragManager._listeners['startdragging']; - startDragListener(event, dragNode); - - // Add shadow node to the workspace. - workspace.append(dragNode); - - me._isDragInProcess = true; - } - - var pos = screen.getWorkspaceMousePosition(event); - dragNode.setPosition(pos.x, pos.y); - - // Call mouse move listeners ... - var dragListener = dragManager._listeners['dragging']; - if ($defined(dragListener)) { - dragListener(event, dragNode); - } - - event.preventDefault(); - - }; - dragManager._mouseMoveListener = result; - return result; - }, - - _buildMouseUpListener : function(workspace, node, dragNode, dragManager) { - var screen = workspace.getScreenManager(); - var me = this; - var result = function(event) { - $assert(dragNode.isDragTopic, 'dragNode must be an DragTopic'); - - // Remove all the events. - screen.removeEvent('mousemove', dragManager._mouseMoveListener); - screen.removeEvent('mouseup', dragManager._mouseUpListener); - - // Help GC - dragManager._mouseMoveListener = null; - dragManager._mouseUpListener = null; - - workspace.enableWorkspaceEvents(true); - // Change the cursor to the default. - window.document.body.style.cursor = 'default'; - - if (me._isDragInProcess) { - - // Execute Listeners only if the node has been moved. - var endDragListener = dragManager._listeners['enddragging']; - endDragListener(event, dragNode); - - // Remove drag node from the workspace. - dragNode.removeFromWorkspace(workspace); - - me._isDragInProcess = false; - } - - - }; - dragManager._mouseUpListener = result; - return result; - }, - - /** - * type: - * - startdragging. - * - dragging - * - enddragging - */ - addEvent : function(type, listener) { - this._listeners[type] = listener; - } -}); - -export default DragManager; +/* + * Copyright [2015] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const DragTopic = require('./DragTopic').default; + +const DragManager = new Class({ + initialize(workspace, eventDispatcher) { + this._workspace = workspace; + this._designerModel = workspace; + this._listeners = {}; + this._isDragInProcess = false; + this._eventDispatcher = eventDispatcher; + DragTopic.init(this._workspace); + }, + + add(node) { + // Add behaviour ... + const workspace = this._workspace; + const screen = workspace.getScreenManager(); + const dragManager = this; + const me = this; + const mouseDownListener = function (event) { + if (workspace.isWorkspaceEventsEnabled()) { + // Disable double drag... + workspace.enableWorkspaceEvents(false); + + // Set initial position. + const layoutManager = me._eventDispatcher.getLayoutManager(); + const dragNode = node.createDragNode(layoutManager); + + // Register mouse move listener ... + const mouseMoveListener = dragManager._buildMouseMoveListener(workspace, dragNode, dragManager); + screen.addEvent('mousemove', mouseMoveListener); + + // Register mouse up listeners ... + const mouseUpListener = dragManager._buildMouseUpListener(workspace, node, dragNode, dragManager); + screen.addEvent('mouseup', mouseUpListener); + + // Change cursor. + window.document.body.style.cursor = 'move'; + } + }; + node.addEvent('mousedown', mouseDownListener); + }, + + remove(node) { + const nodes = this._topics; + let contained = false; + let index = -1; + for (let i = 0; i < nodes.length; i++) { + if (nodes[i] == node) { + contained = true; + index = i; + } + } + }, + + _buildMouseMoveListener(workspace, dragNode, dragManager) { + const screen = workspace.getScreenManager(); + const me = this; + const result = function (event) { + if (!me._isDragInProcess) { + // Execute Listeners .. + const startDragListener = dragManager._listeners.startdragging; + startDragListener(event, dragNode); + + // Add shadow node to the workspace. + workspace.append(dragNode); + + me._isDragInProcess = true; + } + + const pos = screen.getWorkspaceMousePosition(event); + dragNode.setPosition(pos.x, pos.y); + + // Call mouse move listeners ... + const dragListener = dragManager._listeners.dragging; + if ($defined(dragListener)) { + dragListener(event, dragNode); + } + + event.preventDefault(); + }; + dragManager._mouseMoveListener = result; + return result; + }, + + _buildMouseUpListener(workspace, node, dragNode, dragManager) { + const screen = workspace.getScreenManager(); + const me = this; + const result = function (event) { + $assert(dragNode.isDragTopic, 'dragNode must be an DragTopic'); + + // Remove all the events. + screen.removeEvent('mousemove', dragManager._mouseMoveListener); + screen.removeEvent('mouseup', dragManager._mouseUpListener); + + // Help GC + dragManager._mouseMoveListener = null; + dragManager._mouseUpListener = null; + + workspace.enableWorkspaceEvents(true); + // Change the cursor to the default. + window.document.body.style.cursor = 'default'; + + if (me._isDragInProcess) { + // Execute Listeners only if the node has been moved. + const endDragListener = dragManager._listeners.enddragging; + endDragListener(event, dragNode); + + // Remove drag node from the workspace. + dragNode.removeFromWorkspace(workspace); + + me._isDragInProcess = false; + } + }; + dragManager._mouseUpListener = result; + return result; + }, + + /** + * type: + * - startdragging. + * - dragging + * - enddragging + */ + addEvent(type, listener) { + this._listeners[type] = listener; + }, +}); + +export default DragManager; diff --git a/packages/mindplot/lib/components/DragPivot.js b/packages/mindplot/lib/components/DragPivot.js index 3234c6b7..c689789e 100644 --- a/packages/mindplot/lib/components/DragPivot.js +++ b/packages/mindplot/lib/components/DragPivot.js @@ -1,238 +1,240 @@ -/* - * Copyright [2015] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -const Core = require('@wismapping/core-js') -const core = Core(); -const web2D = require('@wismapping/web2d') -const web2d = web2D(); - -const DragTopic = require('./DragTopic').default; -const Shape = require('./util/Shape').default; -const INodeModel = require('./model/INodeModel').default; - -const DragPivot = new Class({ - initialize:function() { - this._position = new core.Point(); - this._size = DragTopic.PIVOT_SIZE; - - this._straightLine = this._buildStraightLine(); - this._curvedLine = this._buildCurvedLine(); - this._dragPivot = this._buildRect(); - this._connectRect = this._buildRect(); - this._targetTopic = null; - this._isVisible = false; - }, - - isVisible:function() { - return this._isVisible; - }, - - getTargetTopic : function() { - return this._targetTopic; - }, - - _buildStraightLine : function() { - var line = new web2d.CurvedLine(); - line.setStyle(web2d.CurvedLine.SIMPLE_LINE); - line.setStroke(1, 'solid', '#CC0033'); - line.setOpacity(0.4); - line.setVisibility(false); - return line; - }, - - _buildCurvedLine : function() { - var line = new web2d.CurvedLine(); - line.setStyle(web2d.CurvedLine.SIMPLE_LINE); - line.setStroke(1, 'solid', '#CC0033'); - line.setOpacity(0.4); - line.setVisibility(false); - return line; - }, - - - _redrawLine : function() { - // Update line position. - $assert(this.getTargetTopic(), 'Illegal invocation. Target node can not be null'); - - var pivotRect = this._getPivotRect(); - - // Pivot position has not changed. In this case, position change is not required. - var targetTopic = this.getTargetTopic(); - var position = this._position; - - // Calculate pivot connection point ... - var size = this._size; - var targetPosition = targetTopic.getPosition(); - var line = this._getConnectionLine(); - - // Update Line position. - var isAtRight = Shape.isAtRight(targetPosition, position); - var pivotPoint = Shape.calculateRectConnectionPoint(position, size, isAtRight); - line.setFrom(pivotPoint.x, pivotPoint.y); - - // Update rect position - var cx = position.x - (parseInt(size.width) / 2); - var cy = position.y - (parseInt(size.height) / 2); - pivotRect.setPosition(cx, cy); - - // Make line visible only when the position has been already changed. - // This solve several strange effects ;) - var targetPoint = targetTopic.workoutIncomingConnectionPoint(pivotPoint); - line.setTo(targetPoint.x, targetPoint.y); - }, - - setPosition : function(point) { - this._position = point; - this._redrawLine(); - }, - - getPosition : function() { - return this._position; - }, - - _buildRect : function() { - var size = this._size; - var rectAttributes = {fillColor:'#CC0033',opacity:0.4,width:size.width,height:size.height,strokeColor:'#FF9933'}; - var rect = new web2d.Rect(0, rectAttributes); - rect.setVisibility(false); - return rect; - }, - - _getPivotRect : function() { - return this._dragPivot; - }, - - getSize : function() { - var elem2d = this._getPivotRect(); - return elem2d.getSize(); - }, - - setVisibility : function(value) { - if (this.isVisible() != value) { - - var pivotRect = this._getPivotRect(); - pivotRect.setVisibility(value); - - var connectRect = this._connectRect; - connectRect.setVisibility(value); - - var line = this._getConnectionLine(); - if (line) { - line.setVisibility(value); - } - this._isVisible = value; - } - }, - - // If the node is connected, validate that there is a line connecting both... - _getConnectionLine : function() { - var result = null; - var parentTopic = this._targetTopic; - if (parentTopic) { - if (parentTopic.getType() == INodeModel.CENTRAL_TOPIC_TYPE) { - result = this._straightLine; - } else { - result = this._curvedLine; - } - } - return result; - }, - - addToWorkspace : function(workspace) { - var pivotRect = this._getPivotRect(); - workspace.append(pivotRect); - - var connectToRect = this._connectRect; - workspace.append(connectToRect); - - // Add a hidden straight line ... - var straighLine = this._straightLine; - straighLine.setVisibility(false); - workspace.append(straighLine); - straighLine.moveToBack(); - - // Add a hidden curved line ... - var curvedLine = this._curvedLine; - curvedLine.setVisibility(false); - workspace.append(curvedLine); - curvedLine.moveToBack(); - - // Add a connect rect ... - var connectRect = this._connectRect; - connectRect.setVisibility(false); - workspace.append(connectRect); - connectRect.moveToBack(); - }, - - removeFromWorkspace : function(workspace) { - var shape = this._getPivotRect(); - workspace.removeChild(shape); - - var connectToRect = this._connectRect; - workspace.removeChild(connectToRect); - - if ($defined(this._straightLine)) { - workspace.removeChild(this._straightLine); - } - - if ($defined(this._curvedLine)) { - workspace.removeChild(this._curvedLine); - } - }, - - connectTo : function(targetTopic, position) { - $assert(!this._outgoingLine, 'Could not connect an already connected node'); - $assert(targetTopic != this, 'Circular connection are not allowed'); - $assert(position, 'position can not be null'); - $assert(targetTopic, 'parent can not be null'); - - this._position = position; - this._targetTopic = targetTopic; - - // Connected to Rect ... - var connectRect = this._connectRect; - var targetSize = targetTopic.getSize(); - - // Add 4 pixel in order to keep create a rect bigger than the topic. - var width = targetSize.width + 4; - var height = targetSize.height + 4; - - connectRect.setSize(width, height); - - var targetPosition = targetTopic.getPosition(); - var cx = Math.ceil(targetPosition.x - (width / 2)); - var cy = Math.ceil(targetPosition.y - (height / 2)); - connectRect.setPosition(cx, cy); - - // Change elements position ... - var pivotRect = this._getPivotRect(); - pivotRect.moveToFront(); - pivotRect.setPosition(position.x, position.y); - - this._redrawLine(); - }, - - disconnect : function(workspace) { - $assert(workspace, 'workspace can not be null.'); - $assert(this._targetTopic, 'There are not connected topic.'); - - this.setVisibility(false); - this._targetTopic = null; - } -}); - -export default DragPivot; +/* + * Copyright [2015] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const Core = require('@wismapping/core-js'); + +const core = Core(); +const web2D = require('@wismapping/web2d'); + +const web2d = web2D(); + +const DragTopic = require('./DragTopic').default; +const Shape = require('./util/Shape').default; +const INodeModel = require('./model/INodeModel').default; + +const DragPivot = new Class({ + initialize() { + this._position = new core.Point(); + this._size = DragTopic.PIVOT_SIZE; + + this._straightLine = this._buildStraightLine(); + this._curvedLine = this._buildCurvedLine(); + this._dragPivot = this._buildRect(); + this._connectRect = this._buildRect(); + this._targetTopic = null; + this._isVisible = false; + }, + + isVisible() { + return this._isVisible; + }, + + getTargetTopic() { + return this._targetTopic; + }, + + _buildStraightLine() { + const line = new web2d.CurvedLine(); + line.setStyle(web2d.CurvedLine.SIMPLE_LINE); + line.setStroke(1, 'solid', '#CC0033'); + line.setOpacity(0.4); + line.setVisibility(false); + return line; + }, + + _buildCurvedLine() { + const line = new web2d.CurvedLine(); + line.setStyle(web2d.CurvedLine.SIMPLE_LINE); + line.setStroke(1, 'solid', '#CC0033'); + line.setOpacity(0.4); + line.setVisibility(false); + return line; + }, + + _redrawLine() { + // Update line position. + $assert(this.getTargetTopic(), 'Illegal invocation. Target node can not be null'); + + const pivotRect = this._getPivotRect(); + + // Pivot position has not changed. In this case, position change is not required. + const targetTopic = this.getTargetTopic(); + const position = this._position; + + // Calculate pivot connection point ... + const size = this._size; + const targetPosition = targetTopic.getPosition(); + const line = this._getConnectionLine(); + + // Update Line position. + const isAtRight = Shape.isAtRight(targetPosition, position); + const pivotPoint = Shape.calculateRectConnectionPoint(position, size, isAtRight); + line.setFrom(pivotPoint.x, pivotPoint.y); + + // Update rect position + const cx = position.x - (parseInt(size.width) / 2); + const cy = position.y - (parseInt(size.height) / 2); + pivotRect.setPosition(cx, cy); + + // Make line visible only when the position has been already changed. + // This solve several strange effects ;) + const targetPoint = targetTopic.workoutIncomingConnectionPoint(pivotPoint); + line.setTo(targetPoint.x, targetPoint.y); + }, + + setPosition(point) { + this._position = point; + this._redrawLine(); + }, + + getPosition() { + return this._position; + }, + + _buildRect() { + const size = this._size; + const rectAttributes = { + fillColor: '#CC0033', opacity: 0.4, width: size.width, height: size.height, strokeColor: '#FF9933', + }; + const rect = new web2d.Rect(0, rectAttributes); + rect.setVisibility(false); + return rect; + }, + + _getPivotRect() { + return this._dragPivot; + }, + + getSize() { + const elem2d = this._getPivotRect(); + return elem2d.getSize(); + }, + + setVisibility(value) { + if (this.isVisible() != value) { + const pivotRect = this._getPivotRect(); + pivotRect.setVisibility(value); + + const connectRect = this._connectRect; + connectRect.setVisibility(value); + + const line = this._getConnectionLine(); + if (line) { + line.setVisibility(value); + } + this._isVisible = value; + } + }, + + // If the node is connected, validate that there is a line connecting both... + _getConnectionLine() { + let result = null; + const parentTopic = this._targetTopic; + if (parentTopic) { + if (parentTopic.getType() == INodeModel.CENTRAL_TOPIC_TYPE) { + result = this._straightLine; + } else { + result = this._curvedLine; + } + } + return result; + }, + + addToWorkspace(workspace) { + const pivotRect = this._getPivotRect(); + workspace.append(pivotRect); + + const connectToRect = this._connectRect; + workspace.append(connectToRect); + + // Add a hidden straight line ... + const straighLine = this._straightLine; + straighLine.setVisibility(false); + workspace.append(straighLine); + straighLine.moveToBack(); + + // Add a hidden curved line ... + const curvedLine = this._curvedLine; + curvedLine.setVisibility(false); + workspace.append(curvedLine); + curvedLine.moveToBack(); + + // Add a connect rect ... + const connectRect = this._connectRect; + connectRect.setVisibility(false); + workspace.append(connectRect); + connectRect.moveToBack(); + }, + + removeFromWorkspace(workspace) { + const shape = this._getPivotRect(); + workspace.removeChild(shape); + + const connectToRect = this._connectRect; + workspace.removeChild(connectToRect); + + if ($defined(this._straightLine)) { + workspace.removeChild(this._straightLine); + } + + if ($defined(this._curvedLine)) { + workspace.removeChild(this._curvedLine); + } + }, + + connectTo(targetTopic, position) { + $assert(!this._outgoingLine, 'Could not connect an already connected node'); + $assert(targetTopic != this, 'Circular connection are not allowed'); + $assert(position, 'position can not be null'); + $assert(targetTopic, 'parent can not be null'); + + this._position = position; + this._targetTopic = targetTopic; + + // Connected to Rect ... + const connectRect = this._connectRect; + const targetSize = targetTopic.getSize(); + + // Add 4 pixel in order to keep create a rect bigger than the topic. + const width = targetSize.width + 4; + const height = targetSize.height + 4; + + connectRect.setSize(width, height); + + const targetPosition = targetTopic.getPosition(); + const cx = Math.ceil(targetPosition.x - (width / 2)); + const cy = Math.ceil(targetPosition.y - (height / 2)); + connectRect.setPosition(cx, cy); + + // Change elements position ... + const pivotRect = this._getPivotRect(); + pivotRect.moveToFront(); + pivotRect.setPosition(position.x, position.y); + + this._redrawLine(); + }, + + disconnect(workspace) { + $assert(workspace, 'workspace can not be null.'); + $assert(this._targetTopic, 'There are not connected topic.'); + + this.setVisibility(false); + this._targetTopic = null; + }, +}); + +export default DragPivot; diff --git a/packages/mindplot/lib/components/DragTopic.js b/packages/mindplot/lib/components/DragTopic.js index f5477229..d876a1f0 100644 --- a/packages/mindplot/lib/components/DragTopic.js +++ b/packages/mindplot/lib/components/DragTopic.js @@ -15,207 +15,206 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const Core = require('@wismapping/core-js') +const Core = require('@wismapping/core-js'); + const core = Core(); -const ActionDispatcher = require('./ActionDispatcher').default +const ActionDispatcher = require('./ActionDispatcher').default; const DragPivot = require('./DragPivot').default; const DragTopic = new Class({ - initialize:function (dragShape, draggedNode, layoutManger) { - $assert(dragShape, 'Rect can not be null.'); - $assert(draggedNode, 'draggedNode can not be null.'); - $assert(layoutManger, 'layoutManger can not be null.'); + initialize(dragShape, draggedNode, layoutManger) { + $assert(dragShape, 'Rect can not be null.'); + $assert(draggedNode, 'draggedNode can not be null.'); + $assert(layoutManger, 'layoutManger can not be null.'); - this._elem2d = dragShape; - this._order = null; - this._draggedNode = draggedNode; - this._layoutManager = layoutManger; - this._position = new core.Point(); - this._isInWorkspace = false; - this._isFreeLayoutEnabled = false; - }, + this._elem2d = dragShape; + this._order = null; + this._draggedNode = draggedNode; + this._layoutManager = layoutManger; + this._position = new core.Point(); + this._isInWorkspace = false; + this._isFreeLayoutEnabled = false; + }, - setOrder:function (order) { - this._order = order; - }, + setOrder(order) { + this._order = order; + }, - setPosition:function (x, y) { - // Update drag shadow position .... - var position = {x:x, y:y}; - if (this.isFreeLayoutOn() && this.isConnected()) { - var _layoutManager = this._layoutManager; - var par = this.getConnectedToTopic(); - position = _layoutManager.predict(par.getId(), this._draggedNode.getId(), position, true).position; - } - this._position.setValue(position.x, position.y); - - // Elements are positioned in the center. - // All topic element must be positioned based on the innerShape. - var draggedNode = this._draggedNode; - var size = draggedNode.getSize(); - var cx = position.x - (position.x > 0 ? 0 : size.width); - var cy = Math.ceil(position.y - (size.height / 2)); - this._elem2d.setPosition(cx, cy); - - // In case is not free, pivot must be draw ... - if (this.isConnected() && !this.isFreeLayoutOn()) { - var parent = this.getConnectedToTopic(); - var predict = this._layoutManager.predict(parent.getId(), this._draggedNode.getId(), this.getPosition()); - if (this._order != predict.order) { - var dragPivot = this._getDragPivot(); - var pivotPosition = predict.position; - dragPivot.connectTo(parent, pivotPosition); - this.setOrder(predict.order); - } - } - }, - - updateFreeLayout:function (event) { - var isFreeEnabled = (event.metaKey && Browser.Platform.mac) || (event.ctrlKey && !Browser.Platform.mac); - if (this.isFreeLayoutOn() != isFreeEnabled) { - var dragPivot = this._getDragPivot(); - dragPivot.setVisibility(!isFreeEnabled); - this._isFreeLayoutEnabled = isFreeEnabled; - } - }, - - setVisibility:function (value) { - var dragPivot = this._getDragPivot(); - dragPivot.setVisibility(value); - }, - - isVisible:function () { - var dragPivot = this._getDragPivot(); - return dragPivot.isVisible(); - }, - - getInnerShape:function () { - return this._elem2d; - }, - - disconnect:function (workspace) { - // Clear connection line ... - var dragPivot = this._getDragPivot(); - dragPivot.disconnect(workspace); - }, - - connectTo:function (parent) { - $assert(parent, 'Parent connection node can not be null.'); - - // Where it should be connected ? - var predict = designer._eventBussDispatcher._layoutManager.predict(parent.getId(), this._draggedNode.getId(), this.getPosition()); - - // Connect pivot ... - var dragPivot = this._getDragPivot(); - var position = predict.position; - dragPivot.connectTo(parent, position); - dragPivot.setVisibility(true); - - this.setOrder(predict.order); - }, - - getDraggedTopic:function () { - return this._draggedNode; - }, - - removeFromWorkspace:function (workspace) { - if (this._isInWorkspace) { - // Remove drag shadow. - workspace.removeChild(this._elem2d); - - // Remove pivot shape. To improve performance it will not be removed. Only the visibility will be changed. - var dragPivot = this._getDragPivot(); - dragPivot.setVisibility(false); - - this._isInWorkspace = false; - } - }, - - isInWorkspace:function () { - return this._isInWorkspace; - }, - - addToWorkspace:function (workspace) { - if (!this._isInWorkspace) { - workspace.append(this._elem2d); - var dragPivot = this._getDragPivot(); - dragPivot.addToWorkspace(workspace); - this._isInWorkspace = true; - } - }, - - _getDragPivot:function () { - return DragTopic.__getDragPivot(); - }, - - getPosition:function () { - return this._position; - }, - - isDragTopic:function () { - return true; - }, - - applyChanges:function (workspace) { - $assert(workspace, 'workspace can not be null'); - - - var actionDispatcher = ActionDispatcher.getInstance(); - var draggedTopic = this.getDraggedTopic(); - var topicId = draggedTopic.getId(); - var position = this.getPosition(); - - if (!this.isFreeLayoutOn()) { - var order = null; - var parent = null; - var isDragConnected = this.isConnected(); - if (isDragConnected) { - var targetTopic = this.getConnectedToTopic(); - order = this._order; - parent = targetTopic; - } - - // If the node is not connected, position based on the original drag topic position. - actionDispatcher.dragTopic(topicId, position, order, parent); - } else { - actionDispatcher.moveTopic(topicId, position); - } - }, - - getConnectedToTopic:function () { - var dragPivot = this._getDragPivot(); - return dragPivot.getTargetTopic(); - }, - - isConnected:function () { - return this.getConnectedToTopic() != null; - }, - - isFreeLayoutOn:function () { -// return this._isFreeLayoutEnabled; - // Disable free layout ... - return false; + setPosition(x, y) { + // Update drag shadow position .... + let position = { x, y }; + if (this.isFreeLayoutOn() && this.isConnected()) { + const { _layoutManager } = this; + const par = this.getConnectedToTopic(); + position = _layoutManager.predict(par.getId(), this._draggedNode.getId(), position, true).position; } + this._position.setValue(position.x, position.y); + + // Elements are positioned in the center. + // All topic element must be positioned based on the innerShape. + const draggedNode = this._draggedNode; + const size = draggedNode.getSize(); + const cx = position.x - (position.x > 0 ? 0 : size.width); + const cy = Math.ceil(position.y - (size.height / 2)); + this._elem2d.setPosition(cx, cy); + + // In case is not free, pivot must be draw ... + if (this.isConnected() && !this.isFreeLayoutOn()) { + const parent = this.getConnectedToTopic(); + const predict = this._layoutManager.predict(parent.getId(), this._draggedNode.getId(), this.getPosition()); + if (this._order != predict.order) { + const dragPivot = this._getDragPivot(); + const pivotPosition = predict.position; + dragPivot.connectTo(parent, pivotPosition); + this.setOrder(predict.order); + } + } + }, + + updateFreeLayout(event) { + const isFreeEnabled = (event.metaKey && Browser.Platform.mac) || (event.ctrlKey && !Browser.Platform.mac); + if (this.isFreeLayoutOn() != isFreeEnabled) { + const dragPivot = this._getDragPivot(); + dragPivot.setVisibility(!isFreeEnabled); + this._isFreeLayoutEnabled = isFreeEnabled; + } + }, + + setVisibility(value) { + const dragPivot = this._getDragPivot(); + dragPivot.setVisibility(value); + }, + + isVisible() { + const dragPivot = this._getDragPivot(); + return dragPivot.isVisible(); + }, + + getInnerShape() { + return this._elem2d; + }, + + disconnect(workspace) { + // Clear connection line ... + const dragPivot = this._getDragPivot(); + dragPivot.disconnect(workspace); + }, + + connectTo(parent) { + $assert(parent, 'Parent connection node can not be null.'); + + // Where it should be connected ? + const predict = designer._eventBussDispatcher._layoutManager.predict(parent.getId(), this._draggedNode.getId(), this.getPosition()); + + // Connect pivot ... + const dragPivot = this._getDragPivot(); + const { position } = predict; + dragPivot.connectTo(parent, position); + dragPivot.setVisibility(true); + + this.setOrder(predict.order); + }, + + getDraggedTopic() { + return this._draggedNode; + }, + + removeFromWorkspace(workspace) { + if (this._isInWorkspace) { + // Remove drag shadow. + workspace.removeChild(this._elem2d); + + // Remove pivot shape. To improve performance it will not be removed. Only the visibility will be changed. + const dragPivot = this._getDragPivot(); + dragPivot.setVisibility(false); + + this._isInWorkspace = false; + } + }, + + isInWorkspace() { + return this._isInWorkspace; + }, + + addToWorkspace(workspace) { + if (!this._isInWorkspace) { + workspace.append(this._elem2d); + const dragPivot = this._getDragPivot(); + dragPivot.addToWorkspace(workspace); + this._isInWorkspace = true; + } + }, + + _getDragPivot() { + return DragTopic.__getDragPivot(); + }, + + getPosition() { + return this._position; + }, + + isDragTopic() { + return true; + }, + + applyChanges(workspace) { + $assert(workspace, 'workspace can not be null'); + + const actionDispatcher = ActionDispatcher.getInstance(); + const draggedTopic = this.getDraggedTopic(); + const topicId = draggedTopic.getId(); + const position = this.getPosition(); + + if (!this.isFreeLayoutOn()) { + let order = null; + let parent = null; + const isDragConnected = this.isConnected(); + if (isDragConnected) { + const targetTopic = this.getConnectedToTopic(); + order = this._order; + parent = targetTopic; + } + + // If the node is not connected, position based on the original drag topic position. + actionDispatcher.dragTopic(topicId, position, order, parent); + } else { + actionDispatcher.moveTopic(topicId, position); + } + }, + + getConnectedToTopic() { + const dragPivot = this._getDragPivot(); + return dragPivot.getTargetTopic(); + }, + + isConnected() { + return this.getConnectedToTopic() != null; + }, + + isFreeLayoutOn() { + // return this._isFreeLayoutEnabled; + // Disable free layout ... + return false; + }, }); -DragTopic.PIVOT_SIZE = {width:50, height:6}; +DragTopic.PIVOT_SIZE = { width: 50, height: 6 }; DragTopic.init = function (workspace) { - - $assert(workspace, "workspace can not be null"); - var pivot = DragTopic.__getDragPivot(); - workspace.append(pivot); + $assert(workspace, 'workspace can not be null'); + const pivot = DragTopic.__getDragPivot(); + workspace.append(pivot); }; DragTopic.__getDragPivot = function () { - var result = DragTopic._dragPivot; - if (!$defined(result)) { - result = new DragPivot(); - DragTopic._dragPivot = result; - } - return result; + let result = DragTopic._dragPivot; + if (!$defined(result)) { + result = new DragPivot(); + DragTopic._dragPivot = result; + } + return result; }; export default DragTopic; diff --git a/packages/mindplot/lib/components/EditorOptions.js b/packages/mindplot/lib/components/EditorOptions.js index be8241ae..5bb66573 100644 --- a/packages/mindplot/lib/components/EditorOptions.js +++ b/packages/mindplot/lib/components/EditorOptions.js @@ -16,11 +16,10 @@ * limitations under the License. */ -const EditorOptions = -{ - LayoutManager:"OriginalLayout", -// LayoutManager:"FreeMindLayout", - textEditor:"TextEditor" +const EditorOptions = { + LayoutManager: 'OriginalLayout', + // LayoutManager:"FreeMindLayout", + textEditor: 'TextEditor', // textEditor:"RichTextEditor" }; diff --git a/packages/mindplot/lib/components/EditorProperties.js b/packages/mindplot/lib/components/EditorProperties.js index 9da213e3..281710a2 100644 --- a/packages/mindplot/lib/components/EditorProperties.js +++ b/packages/mindplot/lib/components/EditorProperties.js @@ -1,38 +1,38 @@ -/* - * Copyright [2015] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -const EditorProperties = new Class({ - initialize: function () { - this._zoom = 0; - this._position = 0; - }, - - setZoom: function (zoom) { - this._zoom = zoom; - }, - - getZoom: function () { - return this._zoom; - }, - - asProperties: function () { - return "zoom=" + this._zoom + "\n"; - } -}); - -export default EditorProperties; +/* + * Copyright [2015] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const EditorProperties = new Class({ + initialize() { + this._zoom = 0; + this._position = 0; + }, + + setZoom(zoom) { + this._zoom = zoom; + }, + + getZoom() { + return this._zoom; + }, + + asProperties() { + return `zoom=${this._zoom}\n`; + }, +}); + +export default EditorProperties; diff --git a/packages/mindplot/lib/components/Events.js b/packages/mindplot/lib/components/Events.js index cfe6e63d..dbad7a59 100644 --- a/packages/mindplot/lib/components/Events.js +++ b/packages/mindplot/lib/components/Events.js @@ -1,45 +1,43 @@ const Events = new Class({ - $events: {}, + $events: {}, - _removeOn: function (string) { - return string.replace(/^on([A-Z])/, function (full, first) { - return first.toLowerCase(); - }); - }, + _removeOn(string) { + return string.replace(/^on([A-Z])/, (full, first) => first.toLowerCase()); + }, - addEvent: function (type, fn, internal) { - type = this._removeOn(type); + addEvent(type, fn, internal) { + type = this._removeOn(type); - this.$events[type] = (this.$events[type] || []).include(fn); - if (internal) fn.internal = true; - return this; - }, + this.$events[type] = (this.$events[type] || []).include(fn); + if (internal) fn.internal = true; + return this; + }, - fireEvent: function (type, args, delay) { - type = this._removeOn(type); - var events = this.$events[type]; - if (!events) return this; - args = Array.isArray(args) ? args : [args]; - _.each( - events, - function (fn) { - if (delay) fn.delay(delay, this, args); - else fn.apply(this, args); - }, - this - ); - return this; - }, + fireEvent(type, args, delay) { + type = this._removeOn(type); + const events = this.$events[type]; + if (!events) return this; + args = Array.isArray(args) ? args : [args]; + _.each( + events, + function (fn) { + if (delay) fn.delay(delay, this, args); + else fn.apply(this, args); + }, + this, + ); + return this; + }, - removeEvent: function (type, fn) { - type = this._removeOn(type); - var events = this.$events[type]; - if (events && !fn.internal) { - var index = events.indexOf(fn); - if (index != -1) events.splice(index, 1); - } - return this; - }, + removeEvent(type, fn) { + type = this._removeOn(type); + const events = this.$events[type]; + if (events && !fn.internal) { + const index = events.indexOf(fn); + if (index != -1) events.splice(index, 1); + } + return this; + }, }); export default Events; diff --git a/packages/mindplot/lib/components/Icon.js b/packages/mindplot/lib/components/Icon.js index 4f1c4c93..b983227a 100644 --- a/packages/mindplot/lib/components/Icon.js +++ b/packages/mindplot/lib/components/Icon.js @@ -15,44 +15,45 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const web2D = require('@wismapping/web2d') -const web2d = web2D() +const web2D = require('@wismapping/web2d'); + +const web2d = web2D(); const Icon = new Class({ - initialize: function (url) { - $assert(url, 'topic can not be null'); - this._image = new web2d.Image(); - this._image.setHref(url); - this._image.setSize(Icon.SIZE, Icon.SIZE); - }, + initialize(url) { + $assert(url, 'topic can not be null'); + this._image = new web2d.Image(); + this._image.setHref(url); + this._image.setSize(Icon.SIZE, Icon.SIZE); + }, - getImage: function () { - return this._image; - }, + getImage() { + return this._image; + }, - setGroup: function (group) { - this._group = group; - }, + setGroup(group) { + this._group = group; + }, - getGroup: function () { - return this._group; - }, + getGroup() { + return this._group; + }, - getSize: function () { - return this._image.getSize(); - }, + getSize() { + return this._image.getSize(); + }, - getPosition: function () { - return this._image.getPosition(); - }, + getPosition() { + return this._image.getPosition(); + }, - addEvent: function (type, fnc) { - this._image.addEvent(type, fnc); - }, + addEvent(type, fnc) { + this._image.addEvent(type, fnc); + }, - remove: function () { - throw "Unsupported operation"; - } + remove() { + throw 'Unsupported operation'; + }, }); Icon.SIZE = 90; diff --git a/packages/mindplot/lib/components/IconGroup.js b/packages/mindplot/lib/components/IconGroup.js index d24d5943..61d85884 100644 --- a/packages/mindplot/lib/components/IconGroup.js +++ b/packages/mindplot/lib/components/IconGroup.js @@ -15,157 +15,154 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const web2D = require('@wismapping/web2d') +const web2D = require('@wismapping/web2d'); + const web2d = web2D(); const Icon = require('./Icon'); -const IconGroup = new Class(/**@lends IconGroup */{ - /** +const IconGroup = new Class(/** @lends IconGroup */{ + /** * @constructs * @param topicId * @param iconSize * @throws will throw an error if topicId is null or undefined * @throws will throw an error if iconSize is null or undefined */ - initialize: function (topicId, iconSize) { - $assert($defined(topicId), "topicId can not be null"); - $assert($defined(iconSize), "iconSize can not be null"); + initialize(topicId, iconSize) { + $assert($defined(topicId), 'topicId can not be null'); + $assert($defined(iconSize), 'iconSize can not be null'); - this._icons = []; - this._group = new web2d.Group({ - width: 0, - height: iconSize, - x: 0, - y: 0, - coordSizeWidth: 0, - coordSizeHeight: 100 - }); - this._removeTip = new IconGroup.RemoveTip(this._group, topicId); - this.seIconSize(iconSize, iconSize); + this._icons = []; + this._group = new web2d.Group({ + width: 0, + height: iconSize, + x: 0, + y: 0, + coordSizeWidth: 0, + coordSizeHeight: 100, + }); + this._removeTip = new IconGroup.RemoveTip(this._group, topicId); + this.seIconSize(iconSize, iconSize); - this._registerListeners(); + this._registerListeners(); + }, - }, + /** */ + setPosition(x, y) { + this._group.setPosition(x, y); + }, - /** */ - setPosition: function (x, y) { - this._group.setPosition(x, y); - }, + /** */ + getPosition() { + return this._group.getPosition(); + }, - /** */ - getPosition: function () { - return this._group.getPosition(); - }, + /** */ + getNativeElement() { + return this._group; + }, - /** */ - getNativeElement: function () { - return this._group; - }, + /** */ + getSize() { + return this._group.getSize(); + }, - /** */ - getSize: function () { - return this._group.getSize(); - }, + /** */ + seIconSize(width, height) { + this._iconSize = { width, height }; + this._resize(this._icons.length); + }, - /** */ - seIconSize: function (width, height) { - this._iconSize = {width: width, height: height}; - this._resize(this._icons.length); - }, - - /** + /** * @param icon the icon to be added to the icon group * @param {Boolean} remove * @throws will throw an error if icon is not defined */ - addIcon: function (icon, remove) { - $defined(icon, "icon is not defined"); + addIcon(icon, remove) { + $defined(icon, 'icon is not defined'); - icon.setGroup(this); - this._icons.push(icon); + icon.setGroup(this); + this._icons.push(icon); - // Adjust group and position ... - this._resize(this._icons.length); - this._positionIcon(icon, this._icons.length - 1); + // Adjust group and position ... + this._resize(this._icons.length); + this._positionIcon(icon, this._icons.length - 1); - var imageShape = icon.getImage(); - this._group.append(imageShape); + const imageShape = icon.getImage(); + this._group.append(imageShape); - // Register event for the group .. - if (remove) { - this._removeTip.decorate(this._topicId, icon); - } - }, - - _findIconFromModel: function (iconModel) { - var result = null; - _.each(this._icons, function (icon) { - var elModel = icon.getModel(); - if (elModel.getId() == iconModel.getId()) { - result = icon; - } - }, this); - - if (result == null) { - throw new Error("Icon can no be found:" + iconModel.getId() + ", Icons:" + this._icons); - } - - return result; - }, - - /** */ - removeIconByModel: function (featureModel) { - $assert(featureModel, "featureModel can not be null"); - - var icon = this._findIconFromModel(featureModel); - this._removeIcon(icon); - }, - - _removeIcon: function (icon) { - $assert(icon, "icon can not be null"); - - this._removeTip.close(0); - this._group.removeChild(icon.getImage()); - - this._icons.erase(icon); - this._resize(this._icons.length); - var me = this; - // Add all again ... - _.each(this._icons, function (elem, i) { - me._positionIcon(elem, i); - }); - }, - - /** */ - moveToFront: function () { - this._group.moveToFront(); - }, - - _registerListeners: function () { - this._group.addEvent('click', function (event) { - // Avoid node creation ... - event.stopPropagation(); - - }); - - this._group.addEvent('dblclick', function (event) { - event.stopPropagation(); - - }); - }, - - _resize: function (iconsLength) { - this._group.setSize(iconsLength * this._iconSize.width, this._iconSize.height); - - var iconSize = Icon.SIZE + (IconGroup.ICON_PADDING * 2); - this._group.setCoordSize(iconsLength * iconSize, iconSize); - }, - - _positionIcon: function (icon, order) { - - var iconSize = Icon.SIZE + (IconGroup.ICON_PADDING * 2); - icon.getImage().setPosition(iconSize * order + IconGroup.ICON_PADDING, IconGroup.ICON_PADDING); + // Register event for the group .. + if (remove) { + this._removeTip.decorate(this._topicId, icon); } + }, + + _findIconFromModel(iconModel) { + let result = null; + _.each(this._icons, (icon) => { + const elModel = icon.getModel(); + if (elModel.getId() == iconModel.getId()) { + result = icon; + } + }, this); + + if (result == null) { + throw new Error(`Icon can no be found:${iconModel.getId()}, Icons:${this._icons}`); + } + + return result; + }, + + /** */ + removeIconByModel(featureModel) { + $assert(featureModel, 'featureModel can not be null'); + + const icon = this._findIconFromModel(featureModel); + this._removeIcon(icon); + }, + + _removeIcon(icon) { + $assert(icon, 'icon can not be null'); + + this._removeTip.close(0); + this._group.removeChild(icon.getImage()); + + this._icons.erase(icon); + this._resize(this._icons.length); + const me = this; + // Add all again ... + _.each(this._icons, (elem, i) => { + me._positionIcon(elem, i); + }); + }, + + /** */ + moveToFront() { + this._group.moveToFront(); + }, + + _registerListeners() { + this._group.addEvent('click', (event) => { + // Avoid node creation ... + event.stopPropagation(); + }); + + this._group.addEvent('dblclick', (event) => { + event.stopPropagation(); + }); + }, + + _resize(iconsLength) { + this._group.setSize(iconsLength * this._iconSize.width, this._iconSize.height); + + const iconSize = Icon.SIZE + (IconGroup.ICON_PADDING * 2); + this._group.setCoordSize(iconsLength * iconSize, iconSize); + }, + + _positionIcon(icon, order) { + const iconSize = Icon.SIZE + (IconGroup.ICON_PADDING * 2); + icon.getImage().setPosition(iconSize * order + IconGroup.ICON_PADDING, IconGroup.ICON_PADDING); + }, }); /** @@ -176,169 +173,164 @@ const IconGroup = new Class(/**@lends IconGroup */{ IconGroup.ICON_PADDING = 5; IconGroup.RemoveTip = new Class(/** @lends IconGroup.RemoveTip */{ - /** + /** * @classdesc inner class of IconGroup * @constructs * @param container */ - initialize: function (container) { - $assert(container, "group can not be null"); - this._fadeElem = container; - }, + initialize(container) { + $assert(container, 'group can not be null'); + this._fadeElem = container; + }, - - /** + /** * @param topicId * @param icon * @throws will throw an error if icon is null or undefined */ - show: function (topicId, icon) { - $assert(icon, 'icon can not be null'); + show(topicId, icon) { + $assert(icon, 'icon can not be null'); - // Nothing to do ... - if (this._activeIcon != icon) { - // If there is an active icon, close it first ... - if (this._activeIcon) { - this.close(0); - } + // Nothing to do ... + if (this._activeIcon != icon) { + // If there is an active icon, close it first ... + if (this._activeIcon) { + this.close(0); + } - // Now, let move the position the icon... - var pos = icon.getPosition(); + // Now, let move the position the icon... + const pos = icon.getPosition(); - // Register events ... - var widget = this._buildWeb2d(); - widget.addEvent('click', function () { - icon.remove(); - }); + // Register events ... + const widget = this._buildWeb2d(); + widget.addEvent('click', () => { + icon.remove(); + }); - var me = this; + const me = this; - widget.addEvent('mouseover', function () { - me.show(topicId, icon); - }); + widget.addEvent('mouseover', () => { + me.show(topicId, icon); + }); - widget.addEvent('mouseout', function () { - me.hide(); - }); + widget.addEvent('mouseout', () => { + me.hide(); + }); - widget.setPosition(pos.x + 80, pos.y - 50); - this._fadeElem.append(widget); + widget.setPosition(pos.x + 80, pos.y - 50); + this._fadeElem.append(widget); - // Setup current element ... - this._activeIcon = icon; - this._widget = widget; + // Setup current element ... + this._activeIcon = icon; + this._widget = widget; + } else { + clearTimeout(this._closeTimeoutId); + } + }, - } else { - clearTimeout(this._closeTimeoutId); - } - }, + /** */ + hide() { + this.close(200); + }, - /** */ - hide: function () { - this.close(200); - }, - - /** + /** * @param delay */ - close: function (delay) { + close(delay) { + // This is not ok, trying to close the same dialog twice ? + if (this._closeTimeoutId) { + clearTimeout(this._closeTimeoutId); + } - // This is not ok, trying to close the same dialog twice ? - if (this._closeTimeoutId) { - clearTimeout(this._closeTimeoutId) - } + const me = this; + if (this._activeIcon) { + const widget = this._widget; + const close = function () { + me._activeIcon = null; + me._fadeElem.removeChild(widget); + me._widget = null; + me._closeTimeoutId = null; + }; - var me = this; - if (this._activeIcon) { - var widget = this._widget; - var close = function () { - me._activeIcon = null; - me._fadeElem.removeChild(widget); - me._widget = null; - me._closeTimeoutId = null; - }; + if (!$defined(delay) || delay == 0) { + close(); + } else { + this._closeTimeoutId = close.delay(delay); + } + } + }, - if (!$defined(delay) || delay == 0) { - close(); - } - else { - this._closeTimeoutId = close.delay(delay); - } - } - }, + _buildWeb2d() { + const result = new web2d.Group({ + width: 10, + height: 10, + x: 0, + y: 0, + coordSizeWidth: 10, + coordSizeHeight: 10, + }); - _buildWeb2d: function () { - var result = new web2d.Group({ - width: 10, - height: 10, - x: 0, - y: 0, - coordSizeWidth: 10, - coordSizeHeight: 10 - }); + const outerRect = new web2d.Rect(0, { + x: 0, + y: 0, + width: 10, + height: 10, + stroke: '0', + fillColor: 'black', + }); + result.append(outerRect); + outerRect.setCursor('pointer'); - var outerRect = new web2d.Rect(0, { - x: 0, - y: 0, - width: 10, - height: 10, - stroke: '0', - fillColor: 'black' - }); - result.append(outerRect); - outerRect.setCursor('pointer'); + const innerRect = new web2d.Rect(0, { + x: 1, + y: 1, + width: 8, + height: 8, + stroke: '1 solid white', + fillColor: 'gray', + }); + result.append(innerRect); - var innerRect = new web2d.Rect(0, { - x: 1, - y: 1, - width: 8, - height: 8, - stroke: '1 solid white', - fillColor: 'gray' - }); - result.append(innerRect); + const line = new web2d.Line({ stroke: '1 solid white' }); + line.setFrom(1, 1); + line.setTo(9, 9); + result.append(line); - var line = new web2d.Line({stroke: '1 solid white'}); - line.setFrom(1, 1); - line.setTo(9, 9); - result.append(line); + const line2 = new web2d.Line({ stroke: '1 solid white' }); + line2.setFrom(1, 9); + line2.setTo(9, 1); + result.append(line2); - var line2 = new web2d.Line({stroke: '1 solid white'}); - line2.setFrom(1, 9); - line2.setTo(9, 1); - result.append(line2); + // Some events ... + result.addEvent('mouseover', () => { + innerRect.setFill('#CC0033'); + }); + result.addEvent('mouseout', () => { + innerRect.setFill('gray'); + }); - // Some events ... - result.addEvent('mouseover', function () { - innerRect.setFill('#CC0033'); - }); - result.addEvent('mouseout', function () { - innerRect.setFill('gray'); - }); + result.setSize(50, 50); + return result; + }, - result.setSize(50, 50); - return result; - }, - - /** + /** * @param topicId * @param icon */ - decorate: function (topicId, icon) { + decorate(topicId, icon) { + const me = this; - var me = this; + if (!icon.__remove) { + icon.addEvent('mouseover', () => { + me.show(topicId, icon); + }); - if (!icon.__remove) { - icon.addEvent('mouseover', function () { - me.show(topicId, icon); - }); - - icon.addEvent('mouseout', function () { - me.hide(); - }); - icon.__remove = true; - } + icon.addEvent('mouseout', () => { + me.hide(); + }); + icon.__remove = true; } + }, }); diff --git a/packages/mindplot/lib/components/ImageIcon.js b/packages/mindplot/lib/components/ImageIcon.js index c7357848..3d0f0f59 100644 --- a/packages/mindplot/lib/components/ImageIcon.js +++ b/packages/mindplot/lib/components/ImageIcon.js @@ -19,148 +19,144 @@ const Icon = require('./Icon').default; const ActionDispatcher = require('./ActionDispatcher').default; const ImageIcon = new Class({ - Extends: Icon, - initialize: function (topic, iconModel, readOnly) { - $assert(iconModel, 'iconModel can not be null'); - $assert(topic, 'topic can not be null'); + Extends: Icon, + initialize(topic, iconModel, readOnly) { + $assert(iconModel, 'iconModel can not be null'); + $assert(topic, 'topic can not be null'); - this._topicId = topic.getId(); - this._featureModel = iconModel; + this._topicId = topic.getId(); + this._featureModel = iconModel; - // Build graph image representation ... - var iconType = iconModel.getIconType(); - var imgUrl = this._getImageUrl(iconType); - this.parent(imgUrl); + // Build graph image representation ... + const iconType = iconModel.getIconType(); + const imgUrl = this._getImageUrl(iconType); + this.parent(imgUrl); - if (!readOnly) { + if (!readOnly) { + // Icon + const image = this.getImage(); + const me = this; + image.addEvent('click', () => { + const iconType = iconModel.getIconType(); + const newIconType = me._getNextFamilyIconId(iconType); + iconModel.setIconType(newIconType); - //Icon - var image = this.getImage(); - var me = this; - image.addEvent('click', function () { - - var iconType = iconModel.getIconType(); - var newIconType = me._getNextFamilyIconId(iconType); - iconModel.setIconType(newIconType); - - var imgUrl = me._getImageUrl(newIconType); - me._image.setHref(imgUrl); - - }); - this._image.setCursor('pointer'); - } - }, - - _getImageUrl: function (iconId) { - return "icons/" + iconId + ".png"; - }, - - getModel: function () { - return this._featureModel; - }, - - _getNextFamilyIconId: function (iconId) { - - var familyIcons = this._getFamilyIcons(iconId); - $assert(familyIcons != null, "Family Icon not found!"); - - var result = null; - for (var i = 0; i < familyIcons.length && result == null; i++) { - if (familyIcons[i] == iconId) { - //Is last one? - if (i == (familyIcons.length - 1)) { - result = familyIcons[0]; - } else { - result = familyIcons[i + 1]; - } - break; - } - } - - return result; - }, - - _getFamilyIcons: function (iconId) { - $assert(iconId != null, "id must not be null"); - $assert(iconId.indexOf("_") != -1, "Invalid icon id (it must contain '_')"); - - var result = null; - for (var i = 0; i < ImageIcon.prototype.ICON_FAMILIES.length; i++) { - var family = ImageIcon.prototype.ICON_FAMILIES[i]; - var iconFamilyId = iconId.substr(0, iconId.indexOf("_")); - - if (family.id == iconFamilyId) { - result = family.icons; - break; - } - } - return result; - }, - - remove: function () { - var actionDispatcher = ActionDispatcher.getInstance(); - var featureId = this._featureModel.getId(); - var topicId = this._topicId; - actionDispatcher.removeFeatureFromTopic(topicId, featureId); + const imgUrl = me._getImageUrl(newIconType); + me._image.setHref(imgUrl); + }); + this._image.setCursor('pointer'); } + }, + + _getImageUrl(iconId) { + return `icons/${iconId}.png`; + }, + + getModel() { + return this._featureModel; + }, + + _getNextFamilyIconId(iconId) { + const familyIcons = this._getFamilyIcons(iconId); + $assert(familyIcons != null, 'Family Icon not found!'); + + let result = null; + for (let i = 0; i < familyIcons.length && result == null; i++) { + if (familyIcons[i] == iconId) { + // Is last one? + if (i == (familyIcons.length - 1)) { + result = familyIcons[0]; + } else { + result = familyIcons[i + 1]; + } + break; + } + } + + return result; + }, + + _getFamilyIcons(iconId) { + $assert(iconId != null, 'id must not be null'); + $assert(iconId.indexOf('_') != -1, "Invalid icon id (it must contain '_')"); + + let result = null; + for (let i = 0; i < ImageIcon.prototype.ICON_FAMILIES.length; i++) { + const family = ImageIcon.prototype.ICON_FAMILIES[i]; + const iconFamilyId = iconId.substr(0, iconId.indexOf('_')); + + if (family.id == iconFamilyId) { + result = family.icons; + break; + } + } + return result; + }, + + remove() { + const actionDispatcher = ActionDispatcher.getInstance(); + const featureId = this._featureModel.getId(); + const topicId = this._topicId; + actionDispatcher.removeFeatureFromTopic(topicId, featureId); + }, }); ImageIcon.prototype.ICON_FAMILIES = [ - {"id": "face", "icons": ["face_plain", "face_sad", "face_crying", "face_smile", "face_surprise", "face_wink"]}, - {"id": "funy", "icons": ["funy_angel", "funy_devilish", "funy_glasses", "funy_grin", "funy_kiss", "funy_monkey"]}, - {"id": "conn", "icons": ["conn_connect", "conn_disconnect"]}, - { - "id": "sport", - "icons": ["sport_basketball", "sport_football", "sport_golf", "sport_raquet", "sport_shuttlecock", "sport_soccer", "sport_tennis"] - }, - {"id": "bulb", "icons": ["bulb_light_on", "bulb_light_off"]}, - {"id": "thumb", "icons": ["thumb_thumb_up", "thumb_thumb_down"]}, - {"id": "tick", "icons": ["tick_tick", "tick_cross"]}, - { - "id": "onoff", - "icons": ["onoff_clock", "onoff_clock_red", "onoff_add", "onoff_delete", "onoff_status_offline", "onoff_status_online"] - }, - { - "id": "money", - "icons": ["money_money", "money_dollar", "money_euro", "money_pound", "money_yen", "money_coins", "money_ruby"] - }, - {"id": "time", "icons": ["time_calendar", "time_clock", "time_hourglass"]}, - { - "id": "number", - "icons": ["number_1", "number_2", "number_3", "number_4", "number_5", "number_6", "number_7", "number_8", "number_9"] - }, - {"id": "chart", "icons": ["chart_bar", "chart_line", "chart_curve", "chart_pie", "chart_organisation"]}, - {"id": "sign", "icons": ["sign_warning", "sign_info", "sign_stop", "sign_help", "sign_cancel"]}, - { - "id": "hard", - "icons": ["hard_cd", "hard_computer", "hard_controller", "hard_driver_disk", "hard_ipod", "hard_keyboard", "hard_mouse", "hard_printer"] - }, - { - "id": "soft", - "icons": ["soft_bug", "soft_cursor", "soft_database_table", "soft_database", "soft_feed", "soft_folder_explore", "soft_rss", "soft_penguin"] - }, - {"id": "arrow", "icons": ["arrow_up", "arrow_down", "arrow_left", "arrow_right"]}, - { - "id": "arrowc", - "icons": ["arrowc_rotate_anticlockwise", "arrowc_rotate_clockwise", "arrowc_turn_left", "arrowc_turn_right"] - }, - {"id": "people", "icons": ["people_group", "people_male1", "people_male2", "people_female1", "people_female2"]}, - {"id": "mail", "icons": ["mail_envelop", "mail_mailbox", "mail_edit", "mail_list"]}, - {"id": "flag", "icons": ["flag_blue", "flag_green", "flag_orange", "flag_pink", "flag_purple", "flag_yellow"]}, - { - "id": "bullet", - "icons": ["bullet_black", "bullet_blue", "bullet_green", "bullet_orange", "bullet_red", "bullet_pink", "bullet_purple"] - }, - {"id": "tag", "icons": ["tag_blue", "tag_green", "tag_orange", "tag_red", "tag_pink", "tag_yellow"]}, - { - "id": "object", - "icons": ["object_bell", "object_clanbomber", "object_key", "object_pencil", "object_phone", "object_magnifier", "object_clip", "object_music", "object_star", "object_wizard", "object_house", "object_cake", "object_camera", "object_palette", "object_rainbow"] - }, - { - "id": "weather", - "icons": ["weather_clear-night", "weather_clear", "weather_few-clouds-night", "weather_few-clouds", "weather_overcast", "weather_severe-alert", "weather_showers-scattered", "weather_showers", "weather_snow", "weather_storm"] - }, - {"id": "task", "icons": ["task_0", "task_25", "task_50", "task_75", "task_100"]} + { id: 'face', icons: ['face_plain', 'face_sad', 'face_crying', 'face_smile', 'face_surprise', 'face_wink'] }, + { id: 'funy', icons: ['funy_angel', 'funy_devilish', 'funy_glasses', 'funy_grin', 'funy_kiss', 'funy_monkey'] }, + { id: 'conn', icons: ['conn_connect', 'conn_disconnect'] }, + { + id: 'sport', + icons: ['sport_basketball', 'sport_football', 'sport_golf', 'sport_raquet', 'sport_shuttlecock', 'sport_soccer', 'sport_tennis'], + }, + { id: 'bulb', icons: ['bulb_light_on', 'bulb_light_off'] }, + { id: 'thumb', icons: ['thumb_thumb_up', 'thumb_thumb_down'] }, + { id: 'tick', icons: ['tick_tick', 'tick_cross'] }, + { + id: 'onoff', + icons: ['onoff_clock', 'onoff_clock_red', 'onoff_add', 'onoff_delete', 'onoff_status_offline', 'onoff_status_online'], + }, + { + id: 'money', + icons: ['money_money', 'money_dollar', 'money_euro', 'money_pound', 'money_yen', 'money_coins', 'money_ruby'], + }, + { id: 'time', icons: ['time_calendar', 'time_clock', 'time_hourglass'] }, + { + id: 'number', + icons: ['number_1', 'number_2', 'number_3', 'number_4', 'number_5', 'number_6', 'number_7', 'number_8', 'number_9'], + }, + { id: 'chart', icons: ['chart_bar', 'chart_line', 'chart_curve', 'chart_pie', 'chart_organisation'] }, + { id: 'sign', icons: ['sign_warning', 'sign_info', 'sign_stop', 'sign_help', 'sign_cancel'] }, + { + id: 'hard', + icons: ['hard_cd', 'hard_computer', 'hard_controller', 'hard_driver_disk', 'hard_ipod', 'hard_keyboard', 'hard_mouse', 'hard_printer'], + }, + { + id: 'soft', + icons: ['soft_bug', 'soft_cursor', 'soft_database_table', 'soft_database', 'soft_feed', 'soft_folder_explore', 'soft_rss', 'soft_penguin'], + }, + { id: 'arrow', icons: ['arrow_up', 'arrow_down', 'arrow_left', 'arrow_right'] }, + { + id: 'arrowc', + icons: ['arrowc_rotate_anticlockwise', 'arrowc_rotate_clockwise', 'arrowc_turn_left', 'arrowc_turn_right'], + }, + { id: 'people', icons: ['people_group', 'people_male1', 'people_male2', 'people_female1', 'people_female2'] }, + { id: 'mail', icons: ['mail_envelop', 'mail_mailbox', 'mail_edit', 'mail_list'] }, + { id: 'flag', icons: ['flag_blue', 'flag_green', 'flag_orange', 'flag_pink', 'flag_purple', 'flag_yellow'] }, + { + id: 'bullet', + icons: ['bullet_black', 'bullet_blue', 'bullet_green', 'bullet_orange', 'bullet_red', 'bullet_pink', 'bullet_purple'], + }, + { id: 'tag', icons: ['tag_blue', 'tag_green', 'tag_orange', 'tag_red', 'tag_pink', 'tag_yellow'] }, + { + id: 'object', + icons: ['object_bell', 'object_clanbomber', 'object_key', 'object_pencil', 'object_phone', 'object_magnifier', 'object_clip', 'object_music', 'object_star', 'object_wizard', 'object_house', 'object_cake', 'object_camera', 'object_palette', 'object_rainbow'], + }, + { + id: 'weather', + icons: ['weather_clear-night', 'weather_clear', 'weather_few-clouds-night', 'weather_few-clouds', 'weather_overcast', 'weather_severe-alert', 'weather_showers-scattered', 'weather_showers', 'weather_snow', 'weather_storm'], + }, + { id: 'task', icons: ['task_0', 'task_25', 'task_50', 'task_75', 'task_100'] }, ]; export default ImageIcon; diff --git a/packages/mindplot/lib/components/Keyboard.js b/packages/mindplot/lib/components/Keyboard.js index eb029b88..0ae86470 100644 --- a/packages/mindplot/lib/components/Keyboard.js +++ b/packages/mindplot/lib/components/Keyboard.js @@ -18,17 +18,17 @@ const Keyboard = new Class({ - initialize: function () { - }, + initialize() { + }, - addShortcut: function (shortcuts, callback) { - if (!$.isArray(shortcuts)) { - shortcuts = [shortcuts]; - } - _.each(shortcuts, function (shortcut) { - $(document).bind('keydown', shortcut, callback); - }); + addShortcut(shortcuts, callback) { + if (!$.isArray(shortcuts)) { + shortcuts = [shortcuts]; } + _.each(shortcuts, (shortcut) => { + $(document).bind('keydown', shortcut, callback); + }); + }, }); diff --git a/packages/mindplot/lib/components/LinkIcon.js b/packages/mindplot/lib/components/LinkIcon.js index abd70335..491597a0 100644 --- a/packages/mindplot/lib/components/LinkIcon.js +++ b/packages/mindplot/lib/components/LinkIcon.js @@ -20,53 +20,51 @@ const LinkIconTooltip = require('./widget/LinkIconTooltip').default; const LinkIcon = new Class({ - Extends: Icon, - initialize: function (topic, linkModel, readOnly) { - $assert(topic, 'topic can not be null'); - $assert(linkModel, 'linkModel can not be null'); + Extends: Icon, + initialize(topic, linkModel, readOnly) { + $assert(topic, 'topic can not be null'); + $assert(linkModel, 'linkModel can not be null'); - this.parent(LinkIcon.IMAGE_URL); - this._linksModel = linkModel; - this._topic = topic; - this._readOnly = readOnly; + this.parent(LinkIcon.IMAGE_URL); + this._linksModel = linkModel; + this._topic = topic; + this._readOnly = readOnly; - this._registerEvents(); - }, + this._registerEvents(); + }, - _registerEvents: function () { - this._image.setCursor('pointer'); - this._tip = new LinkIconTooltip(this); + _registerEvents() { + this._image.setCursor('pointer'); + this._tip = new LinkIconTooltip(this); - var me = this; - if (!this._readOnly) { - // Add on click event to open the editor ... - this.addEvent('click', function (event) { - me._tip.hide(); - me._topic.showLinkEditor(); - event.stopPropagation(); - }); - //FIXME: we shouldn't have timeout of that.. - this.addEvent("mouseleave", function (event) { - window.setTimeout(function () { - if (!$("#linkPopover:hover").length) { - me._tip.hide(); - } - event.stopPropagation(); - }, 100) - }); - } - - $(this.getImage()._peer._native).mouseenter(function () { - me._tip.show(); - }) - }, - - getModel: function () { - return this._linksModel; + const me = this; + if (!this._readOnly) { + // Add on click event to open the editor ... + this.addEvent('click', (event) => { + me._tip.hide(); + me._topic.showLinkEditor(); + event.stopPropagation(); + }); + // FIXME: we shouldn't have timeout of that.. + this.addEvent('mouseleave', (event) => { + window.setTimeout(() => { + if (!$('#linkPopover:hover').length) { + me._tip.hide(); + } + event.stopPropagation(); + }, 100); + }); } + + $(this.getImage()._peer._native).mouseenter(() => { + me._tip.show(); + }); + }, + + getModel() { + return this._linksModel; + }, }); -LinkIcon.IMAGE_URL = "images/links.png"; +LinkIcon.IMAGE_URL = 'images/links.png'; export default LinkIcon; - - diff --git a/packages/mindplot/lib/components/LocalStorageManager.js b/packages/mindplot/lib/components/LocalStorageManager.js index 8e6bd77b..ed2358d1 100644 --- a/packages/mindplot/lib/components/LocalStorageManager.js +++ b/packages/mindplot/lib/components/LocalStorageManager.js @@ -18,47 +18,46 @@ const PersistenceManager = require('./PersistenceManager').default; const LocalStorageManager = new Class({ - Extends: PersistenceManager, - initialize: function (documentUrl, forceLoad) { - this.parent(); - this.documentUrl = documentUrl; - this.forceLoad = forceLoad; + Extends: PersistenceManager, + initialize(documentUrl, forceLoad) { + this.parent(); + this.documentUrl = documentUrl; + this.forceLoad = forceLoad; + }, + + saveMapXml(mapId, mapXml, pref, saveHistory, events) { + localStorage.setItem(`${mapId}-xml`, mapXml); + }, + + discardChanges(mapId) { + localStorage.removeItem(`${mapId}-xml`); + }, + + loadMapDom(mapId) { + let xml = localStorage.getItem(`${mapId}-xml`); + if (xml == null || this.forceLoad) { + $.ajax({ + url: this.documentUrl.replace('{id}', mapId), + headers: { 'Content-Type': 'text/plain', Accept: 'application/xml' }, + type: 'get', + dataType: 'text', + async: false, + success(response) { + xml = response; }, - - saveMapXml: function (mapId, mapXml, pref, saveHistory, events) { - localStorage.setItem(mapId + "-xml", mapXml); - }, - - discardChanges: function (mapId) { - localStorage.removeItem(mapId + "-xml"); - }, - - loadMapDom: function (mapId) { - var xml = localStorage.getItem(mapId + "-xml"); - if (xml == null || this.forceLoad) { - $.ajax({ - url: this.documentUrl.replace("{id}", mapId), - headers: {"Content-Type": "text/plain", "Accept": "application/xml"}, - type: 'get', - dataType: "text", - async: false, - success: function (response) { - xml = response; - } - }); - // If I could not load it from a file, hard code one. - if (xml == null) { - throw new Error("Map could not be loaded"); - } - } - - return jQuery.parseXML(xml); - }, - - unlockMap: function (mindmap) { - // Ignore, no implementation required ... - } + }); + // If I could not load it from a file, hard code one. + if (xml == null) { + throw new Error('Map could not be loaded'); + } } -); + + return jQuery.parseXML(xml); + }, + + unlockMap(mindmap) { + // Ignore, no implementation required ... + }, +}); export default LocalStorageManager; diff --git a/packages/mindplot/lib/components/MainTopic.js b/packages/mindplot/lib/components/MainTopic.js index 9f8ab310..6eab42bf 100644 --- a/packages/mindplot/lib/components/MainTopic.js +++ b/packages/mindplot/lib/components/MainTopic.js @@ -1,169 +1,170 @@ -/* - * Copyright [2015] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -const Core = require('@wismapping/core-js') -const core = Core(); -const web2D = require('@wismapping/web2d'); -const web2d = web2D(); - -const Topic = require('./Topic').default; -const { TopicShape } = require('./model/INodeModel'); -const Shape = require('./util/Shape').default; - -const MainTopic = new Class(/** @lends MainTopic */ { - Extends: Topic, - /** - * @extends mindplot.Topic - * @constructs - * @param model - * @param options - */ - initialize: function (model, options) { - this.parent(model, options); - }, - - INNER_RECT_ATTRIBUTES: { stroke: '0.5 solid #009900' }, - - _buildDragShape: function () { - var innerShape = this._buildShape(this.INNER_RECT_ATTRIBUTES, this.getShapeType()); - var size = this.getSize(); - innerShape.setSize(size.width, size.height); - innerShape.setPosition(0, 0); - innerShape.setOpacity(0.5); - innerShape.setCursor('default'); - innerShape.setVisibility(true); - - var brColor = this.getBorderColor(); - innerShape.setAttribute('strokeColor', brColor); - - var bgColor = this.getBackgroundColor(); - innerShape.setAttribute('fillColor', bgColor); - - // Create group ... - var groupAttributes = { - width: 100, - height: 100, - coordSizeWidth: 100, - coordSizeHeight: 100, - }; - var group = new web2d.Group(groupAttributes); - group.append(innerShape); - - // Add Text ... - if (this.getShapeType() != TopicShape.IMAGE) { - var textShape = this._buildTextShape(true); - var text = this.getText(); - textShape.setText(text); - textShape.setOpacity(0.5); - group.append(textShape); - } - return group; - }, - - /** */ - updateTopicShape: function (targetTopic, workspace) { - // Change figure based on the connected topic ... - var model = this.getModel(); - var shapeType = model.getShapeType(); - if (!targetTopic.isCentralTopic()) { - if (!$defined(shapeType)) { - // Get the real shape type ... - shapeType = this.getShapeType(); - this._setShapeType(shapeType, false); - } - } - }, - - /** */ - disconnect: function (workspace) { - this.parent(workspace); - var size = this.getSize(); - - var model = this.getModel(); - var shapeType = model.getShapeType(); - if (!$defined(shapeType)) { - // Change figure ... - shapeType = this.getShapeType(); - this._setShapeType(TopicShape.ROUNDED_RECT, false); - } - var innerShape = this.getInnerShape(); - innerShape.setVisibility(true); - }, - - _updatePositionOnChangeSize: function (oldSize, newSize) { - var xOffset = Math.round((newSize.width - oldSize.width) / 2); - var pos = this.getPosition(); - if ($defined(pos)) { - if (pos.x > 0) { - pos.x = pos.x + xOffset; - } else { - pos.x = pos.x - xOffset; - } - this.setPosition(pos); - } - }, - - /** */ - workoutIncomingConnectionPoint: function (sourcePosition) { - return Shape.workoutIncomingConnectionPoint(this, sourcePosition); - }, - - /** */ - workoutOutgoingConnectionPoint: function (targetPosition) { - $assert(targetPosition, 'targetPoint can not be null'); - var pos = this.getPosition(); - var isAtRight = Shape.isAtRight(targetPosition, pos); - var size = this.getSize(); - - var result; - if (this.getShapeType() == TopicShape.LINE) { - result = new core.Point(); - var groupPosition = this._elem2d.getPosition(); - var innerShareSize = this.getInnerShape().getSize(); - - if (innerShareSize) { - var magicCorrectionNumber = 0.3; - if (!isAtRight) { - result.x = groupPosition.x + innerShareSize.width - magicCorrectionNumber; - } else { - result.x = groupPosition.x + magicCorrectionNumber; - } - result.y = groupPosition.y + innerShareSize.height; - } else { - // Hack: When the size has not being defined. This is because the node has not being added. - // Try to do our best ... - if (!isAtRight) { - result.x = pos.x + size.width / 2; - } else { - result.x = pos.x - size.width / 2; - } - result.y = pos.y + size.height / 2; - } - } else { - result = Shape.calculateRectConnectionPoint( - pos, - size, - isAtRight, - true - ); - } - return result; - }, - } -); - -export default MainTopic; +/* + * Copyright [2015] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const Core = require('@wismapping/core-js'); + +const core = Core(); +const web2D = require('@wismapping/web2d'); + +const web2d = web2D(); + +const Topic = require('./Topic').default; +const { TopicShape } = require('./model/INodeModel'); +const Shape = require('./util/Shape').default; + +const MainTopic = new Class(/** @lends MainTopic */ { + Extends: Topic, + /** + * @extends mindplot.Topic + * @constructs + * @param model + * @param options + */ + initialize(model, options) { + this.parent(model, options); + }, + + INNER_RECT_ATTRIBUTES: { stroke: '0.5 solid #009900' }, + + _buildDragShape() { + const innerShape = this._buildShape(this.INNER_RECT_ATTRIBUTES, this.getShapeType()); + const size = this.getSize(); + innerShape.setSize(size.width, size.height); + innerShape.setPosition(0, 0); + innerShape.setOpacity(0.5); + innerShape.setCursor('default'); + innerShape.setVisibility(true); + + const brColor = this.getBorderColor(); + innerShape.setAttribute('strokeColor', brColor); + + const bgColor = this.getBackgroundColor(); + innerShape.setAttribute('fillColor', bgColor); + + // Create group ... + const groupAttributes = { + width: 100, + height: 100, + coordSizeWidth: 100, + coordSizeHeight: 100, + }; + const group = new web2d.Group(groupAttributes); + group.append(innerShape); + + // Add Text ... + if (this.getShapeType() != TopicShape.IMAGE) { + const textShape = this._buildTextShape(true); + const text = this.getText(); + textShape.setText(text); + textShape.setOpacity(0.5); + group.append(textShape); + } + return group; + }, + + /** */ + updateTopicShape(targetTopic, workspace) { + // Change figure based on the connected topic ... + const model = this.getModel(); + let shapeType = model.getShapeType(); + if (!targetTopic.isCentralTopic()) { + if (!$defined(shapeType)) { + // Get the real shape type ... + shapeType = this.getShapeType(); + this._setShapeType(shapeType, false); + } + } + }, + + /** */ + disconnect(workspace) { + this.parent(workspace); + const size = this.getSize(); + + const model = this.getModel(); + let shapeType = model.getShapeType(); + if (!$defined(shapeType)) { + // Change figure ... + shapeType = this.getShapeType(); + this._setShapeType(TopicShape.ROUNDED_RECT, false); + } + const innerShape = this.getInnerShape(); + innerShape.setVisibility(true); + }, + + _updatePositionOnChangeSize(oldSize, newSize) { + const xOffset = Math.round((newSize.width - oldSize.width) / 2); + const pos = this.getPosition(); + if ($defined(pos)) { + if (pos.x > 0) { + pos.x += xOffset; + } else { + pos.x -= xOffset; + } + this.setPosition(pos); + } + }, + + /** */ + workoutIncomingConnectionPoint(sourcePosition) { + return Shape.workoutIncomingConnectionPoint(this, sourcePosition); + }, + + /** */ + workoutOutgoingConnectionPoint(targetPosition) { + $assert(targetPosition, 'targetPoint can not be null'); + const pos = this.getPosition(); + const isAtRight = Shape.isAtRight(targetPosition, pos); + const size = this.getSize(); + + let result; + if (this.getShapeType() == TopicShape.LINE) { + result = new core.Point(); + const groupPosition = this._elem2d.getPosition(); + const innerShareSize = this.getInnerShape().getSize(); + + if (innerShareSize) { + const magicCorrectionNumber = 0.3; + if (!isAtRight) { + result.x = groupPosition.x + innerShareSize.width - magicCorrectionNumber; + } else { + result.x = groupPosition.x + magicCorrectionNumber; + } + result.y = groupPosition.y + innerShareSize.height; + } else { + // Hack: When the size has not being defined. This is because the node has not being added. + // Try to do our best ... + if (!isAtRight) { + result.x = pos.x + size.width / 2; + } else { + result.x = pos.x - size.width / 2; + } + result.y = pos.y + size.height / 2; + } + } else { + result = Shape.calculateRectConnectionPoint( + pos, + size, + isAtRight, + true, + ); + } + return result; + }, +}); + +export default MainTopic; diff --git a/packages/mindplot/lib/components/Messages.js b/packages/mindplot/lib/components/Messages.js index 93a16a42..49cf03e4 100644 --- a/packages/mindplot/lib/components/Messages.js +++ b/packages/mindplot/lib/components/Messages.js @@ -17,27 +17,27 @@ */ const Messages = new Class({ - Static: { - init: function (locale) { - locale = $defined(locale) ? locale : 'en'; - var bundle = Messages.BUNDLES[locale]; - if (bundle == null && locale.indexOf('_') != -1) { - // Try to locate without the specialization ... - locale = locale.substring(0, locale.indexOf('_')); - bundle = Messages.BUNDLES[locale]; - } - Messages.__bundle = bundle; - }, + Static: { + init(locale) { + locale = $defined(locale) ? locale : 'en'; + let bundle = Messages.BUNDLES[locale]; + if (bundle == null && locale.indexOf('_') != -1) { + // Try to locate without the specialization ... + locale = locale.substring(0, locale.indexOf('_')); + bundle = Messages.BUNDLES[locale]; + } + Messages.__bundle = bundle; }, + }, }); global.$msg = function (key) { - if (!Messages.__bundle) { - Messages.init('en'); - } + if (!Messages.__bundle) { + Messages.init('en'); + } - var msg = Messages.__bundle[key]; - return msg ? msg : key; + const msg = Messages.__bundle[key]; + return msg || key; }; Messages.BUNDLES = {}; diff --git a/packages/mindplot/lib/components/MultilineTextEditor.js b/packages/mindplot/lib/components/MultilineTextEditor.js index 8627bbc0..c6a4fabc 100644 --- a/packages/mindplot/lib/components/MultilineTextEditor.js +++ b/packages/mindplot/lib/components/MultilineTextEditor.js @@ -19,298 +19,285 @@ const Events = require('./Events').default; const ActionDispatcher = require('./ActionDispatcher').default; const MultilineTextEditor = new Class({ - Extends: Events, - initialize: function () { - this._topic = null; - this._timeoutId = -1; - }, + Extends: Events, + initialize() { + this._topic = null; + this._timeoutId = -1; + }, - _buildEditor: function () { + _buildEditor() { + const result = $('
') + .attr('id', 'textContainer') + .css({ + display: 'none', + zIndex: '8', + overflow: 'hidden', + border: '0 none', + }); - var result = $('
') - .attr('id', 'textContainer') - .css({ - display: "none", - zIndex: "8", - overflow: "hidden", - border: "0 none" - }); + const textareaElem = $('') + .css({ + border: '1px gray dashed', + background: 'rgba(98, 135, 167, .3)', + outline: '0 none', + resize: 'none', + overflow: 'hidden', + }); + result.append(textareaElem); + return result; + }, - var textareaElem = $('') - .css({ - border: "1px gray dashed", - background: "rgba(98, 135, 167, .3)", - outline: '0 none', - resize: 'none', - overflow: "hidden" - }); - - result.append(textareaElem); - return result; - }, - - _registerEvents: function (containerElem) { - var textareaElem = this._getTextareaElem(); - var me = this; - textareaElem.on('keydown', function (event) { - switch (jQuery.hotkeys.specialKeys[event.keyCode]) { - case 'esc': - me.close(false); - break; - case 'enter': - if (event.metaKey || event.ctrlKey) { - - // Add return ... - var text = textareaElem.val(); - var cursorPosition = text.length; - if (textareaElem.selectionStart) { - cursorPosition = textareaElem.selectionStart; - } - - var head = text.substring(0, cursorPosition); - var tail = ""; - if (cursorPosition < text.length) { - tail = text.substring(cursorPosition, text.length); - } - textareaElem.val(head + "\n" + tail); - - // Position cursor ... - if (textareaElem[0].setSelectionRange) { - textareaElem.focus(); - textareaElem[0].setSelectionRange(cursorPosition + 1, cursorPosition + 1); - } else if (textareaElem.createTextRange) { - var range = textareaElem.createTextRange(); - range.moveStart('character', cursorPosition + 1); - range.select(); - } - - } - else { - me.close(true); - } - break; - case 'tab': - event.preventDefault(); - var start = $(this).get(0).selectionStart; - var end = $(this).get(0).selectionEnd; - - // set textarea value to: text before caret + tab + text after caret - $(this).val($(this).val().substring(0, start) + "\t" + $(this).val().substring(end)); - - // put caret at right position again - $(this).get(0).selectionStart = $(this).get(0).selectionEnd = start + 1; - break; - } - event.stopPropagation(); - }); - - textareaElem.on('keypress', function (event) { - event.stopPropagation(); - }); - - textareaElem.on('keyup', function (event) { - var text = me._getTextareaElem().val(); - me.fireEvent('input', [event, text]); - me._adjustEditorSize(); - }); - - // If the user clicks on the input, all event must be ignored ... - containerElem.on('click', function (event) { - event.stopPropagation(); - }); - containerElem.on('dblclick', function (event) { - event.stopPropagation(); - }); - containerElem.on('mousedown', function (event) { - event.stopPropagation(); - }); - }, - - _adjustEditorSize: function () { - - if (this.isVisible()) { - var textElem = this._getTextareaElem(); - - var lines = textElem.val().split('\n'); - var maxLineLength = 1; - _.each(lines, function (line) { - if (maxLineLength < line.length) - maxLineLength = line.length; - }); - - textElem.attr('cols', maxLineLength); - textElem.attr('rows', lines.length); - - this._containerElem.css({ - width: (maxLineLength + 3) + 'em', - height: textElem.height() - }); - } - }, - - isVisible: function () { - return $defined(this._containerElem) && this._containerElem.css('display') == 'block'; - }, - - _updateModel: function () { - - if (this._topic.getText() != this._getText()) { - var text = this._getText(); - var topicId = this._topic.getId(); - - var actionDispatcher = ActionDispatcher.getInstance(); - actionDispatcher.changeTextToTopic([topicId], text); - } - }, - - show: function (topic, text) { - // Close a previous node editor if it's opened ... - if (this._topic) { - this.close(false); - } - - this._topic = topic; - if (!this.isVisible()) { - //Create editor ui - var containerElem = this._buildEditor(); - $('body').append(containerElem); - - this._containerElem = containerElem; - this._registerEvents(containerElem); - this._showEditor(text); - } - }, - - _showEditor: function (defaultText) { - - var topic = this._topic; - - // Hide topic text ... - topic.getTextShape().setVisibility(false); - - // Set Editor Style - var nodeText = topic.getTextShape(); - var font = nodeText.getFont(); - font.size = nodeText.getHtmlFontSize(); - font.color = nodeText.getColor(); - this._setStyle(font); - var me = this; - // Set editor's initial size - var displayFunc = function () { - // Position the editor and set the size... - var textShape = topic.getTextShape(); - - me._containerElem.css('display', 'block'); - - //FIXME: Im not sure if this is best way... - var shapePosition = textShape.getNativePosition(); - me._containerElem.offset(shapePosition); - - // Set editor's initial text ... - var text = $defined(defaultText) ? defaultText : topic.getText(); - me._setText(text); - - // Set the element focus and select the current text ... - var inputElem = me._getTextareaElem(); - me._positionCursor(inputElem, !$defined(defaultText)); - - }; - - this._timeoutId = displayFunc.delay(10); - }, - - _setStyle: function (fontStyle) { - var inputField = this._getTextareaElem(); - if (!$defined(fontStyle.font)) { - fontStyle.font = "Arial"; - } - if (!$defined(fontStyle.style)) { - fontStyle.style = "normal"; - } - if (!$defined(fontStyle.weight)) { - fontStyle.weight = "normal"; - } - if (!$defined(fontStyle.size)) { - fontStyle.size = 12; - } - var style = { - fontSize: fontStyle.size + "px", - fontFamily: fontStyle.font, - fontStyle: fontStyle.style, - fontWeight: fontStyle.weight, - color: fontStyle.color - }; - inputField.css(style); - this._containerElem.css(style); - }, - - _setText: function (text) { - var textareaElem = this._getTextareaElem(); - textareaElem.val(text); - this._adjustEditorSize(); - }, - - _getText: function () { - return this._getTextareaElem().val(); - }, - - _getTextareaElem: function () { - return this._containerElem.find('textarea'); - }, - - _positionCursor: function (textareaElem, selectText) { - textareaElem.focus(); - var lengh = textareaElem.val().length; - if (selectText) { - // Mark text as selected ... - if (textareaElem.createTextRange) { - var rang = textareaElem.createTextRange(); - rang.select(); - rang.move("character", lengh); - } - else { - textareaElem[0].setSelectionRange(0, lengh); + _registerEvents(containerElem) { + const textareaElem = this._getTextareaElem(); + const me = this; + textareaElem.on('keydown', function (event) { + switch (jQuery.hotkeys.specialKeys[event.keyCode]) { + case 'esc': + me.close(false); + break; + case 'enter': + if (event.metaKey || event.ctrlKey) { + // Add return ... + const text = textareaElem.val(); + let cursorPosition = text.length; + if (textareaElem.selectionStart) { + cursorPosition = textareaElem.selectionStart; } - } else { - // Move the cursor to the last character .. - if (textareaElem.createTextRange) { - var range = textareaElem.createTextRange(); - range.move("character", lengh); - } else { - if (Browser.ie11) { - textareaElem[0].selectionStart = lengh; - textareaElem[0].selectionEnd = lengh; - } else { - textareaElem.selectionStart = lengh; - textareaElem.selectionEnd = lengh; - } - textareaElem.focus(); + const head = text.substring(0, cursorPosition); + let tail = ''; + if (cursorPosition < text.length) { + tail = text.substring(cursorPosition, text.length); } - } + textareaElem.val(`${head}\n${tail}`); - }, - - close: function (update) { - if (this.isVisible() && this._topic) { - // Update changes ... - clearTimeout(this._timeoutId); - - if (!$defined(update) || update) { - this._updateModel(); + // Position cursor ... + if (textareaElem[0].setSelectionRange) { + textareaElem.focus(); + textareaElem[0].setSelectionRange(cursorPosition + 1, cursorPosition + 1); + } else if (textareaElem.createTextRange) { + const range = textareaElem.createTextRange(); + range.moveStart('character', cursorPosition + 1); + range.select(); } + } else { + me.close(true); + } + break; + case 'tab': + event.preventDefault(); + var start = $(this).get(0).selectionStart; + var end = $(this).get(0).selectionEnd; - // Let make the visible text in the node visible again ... - this._topic.getTextShape().setVisibility(true); + // set textarea value to: text before caret + tab + text after caret + $(this).val(`${$(this).val().substring(0, start)}\t${$(this).val().substring(end)}`); - // Remove it form the screen ... - this._containerElem.remove(); - this._containerElem = null; - this._timeoutId = -1; - } - this._topic = null; + // put caret at right position again + $(this).get(0).selectionStart = $(this).get(0).selectionEnd = start + 1; + break; + } + event.stopPropagation(); + }); + + textareaElem.on('keypress', (event) => { + event.stopPropagation(); + }); + + textareaElem.on('keyup', (event) => { + const text = me._getTextareaElem().val(); + me.fireEvent('input', [event, text]); + me._adjustEditorSize(); + }); + + // If the user clicks on the input, all event must be ignored ... + containerElem.on('click', (event) => { + event.stopPropagation(); + }); + containerElem.on('dblclick', (event) => { + event.stopPropagation(); + }); + containerElem.on('mousedown', (event) => { + event.stopPropagation(); + }); + }, + + _adjustEditorSize() { + if (this.isVisible()) { + const textElem = this._getTextareaElem(); + + const lines = textElem.val().split('\n'); + let maxLineLength = 1; + _.each(lines, (line) => { + if (maxLineLength < line.length) maxLineLength = line.length; + }); + + textElem.attr('cols', maxLineLength); + textElem.attr('rows', lines.length); + + this._containerElem.css({ + width: `${maxLineLength + 3}em`, + height: textElem.height(), + }); } + }, + + isVisible() { + return $defined(this._containerElem) && this._containerElem.css('display') == 'block'; + }, + + _updateModel() { + if (this._topic.getText() != this._getText()) { + const text = this._getText(); + const topicId = this._topic.getId(); + + const actionDispatcher = ActionDispatcher.getInstance(); + actionDispatcher.changeTextToTopic([topicId], text); + } + }, + + show(topic, text) { + // Close a previous node editor if it's opened ... + if (this._topic) { + this.close(false); + } + + this._topic = topic; + if (!this.isVisible()) { + // Create editor ui + const containerElem = this._buildEditor(); + $('body').append(containerElem); + + this._containerElem = containerElem; + this._registerEvents(containerElem); + this._showEditor(text); + } + }, + + _showEditor(defaultText) { + const topic = this._topic; + + // Hide topic text ... + topic.getTextShape().setVisibility(false); + + // Set Editor Style + const nodeText = topic.getTextShape(); + const font = nodeText.getFont(); + font.size = nodeText.getHtmlFontSize(); + font.color = nodeText.getColor(); + this._setStyle(font); + const me = this; + // Set editor's initial size + const displayFunc = function () { + // Position the editor and set the size... + const textShape = topic.getTextShape(); + + me._containerElem.css('display', 'block'); + + // FIXME: Im not sure if this is best way... + const shapePosition = textShape.getNativePosition(); + me._containerElem.offset(shapePosition); + + // Set editor's initial text ... + const text = $defined(defaultText) ? defaultText : topic.getText(); + me._setText(text); + + // Set the element focus and select the current text ... + const inputElem = me._getTextareaElem(); + me._positionCursor(inputElem, !$defined(defaultText)); + }; + + this._timeoutId = displayFunc.delay(10); + }, + + _setStyle(fontStyle) { + const inputField = this._getTextareaElem(); + if (!$defined(fontStyle.font)) { + fontStyle.font = 'Arial'; + } + if (!$defined(fontStyle.style)) { + fontStyle.style = 'normal'; + } + if (!$defined(fontStyle.weight)) { + fontStyle.weight = 'normal'; + } + if (!$defined(fontStyle.size)) { + fontStyle.size = 12; + } + const style = { + fontSize: `${fontStyle.size}px`, + fontFamily: fontStyle.font, + fontStyle: fontStyle.style, + fontWeight: fontStyle.weight, + color: fontStyle.color, + }; + inputField.css(style); + this._containerElem.css(style); + }, + + _setText(text) { + const textareaElem = this._getTextareaElem(); + textareaElem.val(text); + this._adjustEditorSize(); + }, + + _getText() { + return this._getTextareaElem().val(); + }, + + _getTextareaElem() { + return this._containerElem.find('textarea'); + }, + + _positionCursor(textareaElem, selectText) { + textareaElem.focus(); + const lengh = textareaElem.val().length; + if (selectText) { + // Mark text as selected ... + if (textareaElem.createTextRange) { + const rang = textareaElem.createTextRange(); + rang.select(); + rang.move('character', lengh); + } else { + textareaElem[0].setSelectionRange(0, lengh); + } + } else { + // Move the cursor to the last character .. + if (textareaElem.createTextRange) { + const range = textareaElem.createTextRange(); + range.move('character', lengh); + } else { + if (Browser.ie11) { + textareaElem[0].selectionStart = lengh; + textareaElem[0].selectionEnd = lengh; + } else { + textareaElem.selectionStart = lengh; + textareaElem.selectionEnd = lengh; + } + textareaElem.focus(); + } + } + }, + + close(update) { + if (this.isVisible() && this._topic) { + // Update changes ... + clearTimeout(this._timeoutId); + + if (!$defined(update) || update) { + this._updateModel(); + } + + // Let make the visible text in the node visible again ... + this._topic.getTextShape().setVisibility(true); + + // Remove it form the screen ... + this._containerElem.remove(); + this._containerElem = null; + this._timeoutId = -1; + } + this._topic = null; + }, }); export default MultilineTextEditor; diff --git a/packages/mindplot/lib/components/NodeGraph.js b/packages/mindplot/lib/components/NodeGraph.js index 92d79bb8..8e047cc2 100644 --- a/packages/mindplot/lib/components/NodeGraph.js +++ b/packages/mindplot/lib/components/NodeGraph.js @@ -20,171 +20,171 @@ const DragTopic = require('./DragTopic').default; const INodeModel = require('./model/INodeModel').default; const NodeGraph = new Class( - /** @lends NodeGraph */ { - /** + /** @lends NodeGraph */ { + /** * @constructs * @param {mindplot.model.NodeModel} nodeModel * @param {Object} options * @throws will throw an error if nodeModel is null or undefined */ - initialize: function (nodeModel, options) { - $assert(nodeModel, 'model can not be null'); + initialize(nodeModel, options) { + $assert(nodeModel, 'model can not be null'); - this._options = options; - this._mouseEvents = true; - this.setModel(nodeModel); - this._onFocus = false; - this._size = { width: 50, height: 20 }; - }, + this._options = options; + this._mouseEvents = true; + this.setModel(nodeModel); + this._onFocus = false; + this._size = { width: 50, height: 20 }; + }, - /** @return true if option is set to read-only */ - isReadOnly: function () { - return this._options.readOnly; - }, + /** @return true if option is set to read-only */ + isReadOnly() { + return this._options.readOnly; + }, - /** @return model type */ - getType: function () { - var model = this.getModel(); - return model.getType(); - }, + /** @return model type */ + getType() { + const model = this.getModel(); + return model.getType(); + }, - /** + /** * @param {String} id * @throws will throw an error if the topic id is not a number */ - setId: function (id) { - $assert(typeof topic.getId() == 'number', 'id is not a number:' + id); - this.getModel().setId(id); - }, + setId(id) { + $assert(typeof topic.getId() === 'number', `id is not a number:${id}`); + this.getModel().setId(id); + }, - _set2DElement: function (elem2d) { - this._elem2d = elem2d; - }, + _set2DElement(elem2d) { + this._elem2d = elem2d; + }, - /** + /** * @return 2D element * @throws will throw an error if the element is null or undefined within node graph */ - get2DElement: function () { - $assert(this._elem2d, 'NodeGraph has not been initialized properly'); - return this._elem2d; - }, + get2DElement() { + $assert(this._elem2d, 'NodeGraph has not been initialized properly'); + return this._elem2d; + }, - /** @abstract */ - setPosition: function (point, fireEvent) { - throw 'Unsupported operation'; - }, + /** @abstract */ + setPosition(point, fireEvent) { + throw 'Unsupported operation'; + }, - /** */ - addEvent: function (type, listener) { - var elem = this.get2DElement(); - elem.addEvent(type, listener); - }, + /** */ + addEvent(type, listener) { + const elem = this.get2DElement(); + elem.addEvent(type, listener); + }, - /** */ - removeEvent: function (type, listener) { - var elem = this.get2DElement(); - elem.removeEvent(type, listener); - }, + /** */ + removeEvent(type, listener) { + const elem = this.get2DElement(); + elem.removeEvent(type, listener); + }, - /** */ - fireEvent: function (type, event) { - var elem = this.get2DElement(); - elem.trigger(type, event); - }, + /** */ + fireEvent(type, event) { + const elem = this.get2DElement(); + elem.trigger(type, event); + }, - /** */ - setMouseEventsEnabled: function (isEnabled) { - this._mouseEvents = isEnabled; - }, + /** */ + setMouseEventsEnabled(isEnabled) { + this._mouseEvents = isEnabled; + }, - /** */ - isMouseEventsEnabled: function () { - return this._mouseEvents; - }, + /** */ + isMouseEventsEnabled() { + return this._mouseEvents; + }, - /** @return {Object} size*/ - getSize: function () { - return this._size; - }, + /** @return {Object} size */ + getSize() { + return this._size; + }, - /** @param {Object} size*/ - setSize: function (size) { - this._size.width = parseInt(size.width); - this._size.height = parseInt(size.height); - }, + /** @param {Object} size */ + setSize(size) { + this._size.width = parseInt(size.width); + this._size.height = parseInt(size.height); + }, - /** + /** * @return {mindplot.model.NodeModel} the node model */ - getModel: function () { - $assert(this._model, 'Model has not been initialized yet'); - return this._model; - }, + getModel() { + $assert(this._model, 'Model has not been initialized yet'); + return this._model; + }, - /** + /** * @param {mindplot.NodeModel} model the node model * @throws will throw an error if model is null or undefined */ - setModel: function (model) { - $assert(model, 'Model can not be null'); - this._model = model; - }, + setModel(model) { + $assert(model, 'Model can not be null'); + this._model = model; + }, - /** */ - getId: function () { - return this._model.getId(); - }, + /** */ + getId() { + return this._model.getId(); + }, - /** */ - setOnFocus: function (focus) { - if (this._onFocus != focus) { - this._onFocus = focus; - var outerShape = this.getOuterShape(); - if (focus) { - outerShape.setFill(Topic.OUTER_SHAPE_ATTRIBUTES_FOCUS.fillColor); - outerShape.setOpacity(1); - } else { - outerShape.setFill(Topic.OUTER_SHAPE_ATTRIBUTES.fillColor); - outerShape.setOpacity(0); - } - this.setCursor('move'); + /** */ + setOnFocus(focus) { + if (this._onFocus != focus) { + this._onFocus = focus; + const outerShape = this.getOuterShape(); + if (focus) { + outerShape.setFill(Topic.OUTER_SHAPE_ATTRIBUTES_FOCUS.fillColor); + outerShape.setOpacity(1); + } else { + outerShape.setFill(Topic.OUTER_SHAPE_ATTRIBUTES.fillColor); + outerShape.setOpacity(0); + } + this.setCursor('move'); - // In any case, always try to hide the editor ... - this.closeEditors(); + // In any case, always try to hide the editor ... + this.closeEditors(); - // Fire event ... - this.fireEvent(focus ? 'ontfocus' : 'ontblur', this); - } - }, + // Fire event ... + this.fireEvent(focus ? 'ontfocus' : 'ontblur', this); + } + }, - /** @return {Boolean} true if the node graph is on focus */ - isOnFocus: function () { - return this._onFocus; - }, + /** @return {Boolean} true if the node graph is on focus */ + isOnFocus() { + return this._onFocus; + }, - /** */ - dispose: function (workspace) { - this.setOnFocus(false); - workspace.removeChild(this); - }, + /** */ + dispose(workspace) { + this.setOnFocus(false); + workspace.removeChild(this); + }, - /** */ - createDragNode: function (layoutManager) { - var dragShape = this._buildDragShape(); - return new DragTopic(dragShape, this, layoutManager); - }, + /** */ + createDragNode(layoutManager) { + const dragShape = this._buildDragShape(); + return new DragTopic(dragShape, this, layoutManager); + }, - _buildDragShape: function () { - $assert(false, '_buildDragShape must be implemented by all nodes.'); - }, + _buildDragShape() { + $assert(false, '_buildDragShape must be implemented by all nodes.'); + }, - /** */ - getPosition: function () { - var model = this.getModel(); - return model.getPosition(); - }, - } + /** */ + getPosition() { + const model = this.getModel(); + return model.getPosition(); + }, + }, ); /** @@ -199,24 +199,24 @@ const NodeGraph = new Class( * @return {mindplot.CentralTopic|mindplot.MainTopic} the new topic */ NodeGraph.create = function (nodeModel, options) { - const CentralTopic = require('./CentralTopic').default; - const MainTopic = require('./MainTopic').default; + const CentralTopic = require('./CentralTopic').default; + const MainTopic = require('./MainTopic').default; - $assert(nodeModel, 'Model can not be null'); + $assert(nodeModel, 'Model can not be null'); - var type = nodeModel.getType(); - $assert(type, 'Node model type can not be null'); + const type = nodeModel.getType(); + $assert(type, 'Node model type can not be null'); - var result; - if (type == INodeModel.CENTRAL_TOPIC_TYPE) { - result = new CentralTopic(nodeModel, options); - } else if (type == INodeModel.MAIN_TOPIC_TYPE) { - result = new MainTopic(nodeModel, options); - } else { - $assert(false, 'unsupported node type:' + type); - } + let result; + if (type == INodeModel.CENTRAL_TOPIC_TYPE) { + result = new CentralTopic(nodeModel, options); + } else if (type == INodeModel.MAIN_TOPIC_TYPE) { + result = new MainTopic(nodeModel, options); + } else { + $assert(false, `unsupported node type:${type}`); + } - return result; + return result; }; export default NodeGraph; diff --git a/packages/mindplot/lib/components/NoteIcon.js b/packages/mindplot/lib/components/NoteIcon.js index da192f1e..a1a4f1da 100644 --- a/packages/mindplot/lib/components/NoteIcon.js +++ b/packages/mindplot/lib/components/NoteIcon.js @@ -19,66 +19,64 @@ const Icon = require('./Icon').default; const FloatingTip = require('./widget/FloatingTip').default; const NoteIcon = new Class({ - Extends: Icon, - initialize: function (topic, noteModel, readOnly) { - $assert(topic, 'topic can not be null'); + Extends: Icon, + initialize(topic, noteModel, readOnly) { + $assert(topic, 'topic can not be null'); - this.parent(NoteIcon.IMAGE_URL); - this._linksModel = noteModel; - this._topic = topic; - this._readOnly = readOnly; + this.parent(NoteIcon.IMAGE_URL); + this._linksModel = noteModel; + this._topic = topic; + this._readOnly = readOnly; - this._registerEvents(); - }, + this._registerEvents(); + }, - _registerEvents: function () { - this._image.setCursor('pointer'); - var me = this; + _registerEvents() { + this._image.setCursor('pointer'); + const me = this; - if (!this._readOnly) { - // Add on click event to open the editor ... - this.addEvent('click', function (event) { - me._topic.showNoteEditor(); - event.stopPropagation(); - }); - } - this._tip = new FloatingTip($(me.getImage()._peer._native), { - title: $msg('NOTE'), - container: 'body', - // Content can also be a function of the target element! - content: function () { - return me._buildTooltipContent(); - }, - html: true, - placement: 'bottom', - destroyOnExit: true - }); - - }, - - _buildTooltipContent: function () { - if ($("body").find("#textPopoverNote").length == 1) { - var text = $("body").find("#textPopoverNote"); - text.text(this._linksModel.getText()); - } else { - var result = $('
').css({padding: '5px'}); - - var text = $('
').text(this._linksModel.getText()) - .css({ - 'white-space': 'pre-wrap', - 'word-wrap': 'break-word' - } - ); - result.append(text); - return result; - } - }, - - getModel: function () { - return this._linksModel; + if (!this._readOnly) { + // Add on click event to open the editor ... + this.addEvent('click', (event) => { + me._topic.showNoteEditor(); + event.stopPropagation(); + }); } + this._tip = new FloatingTip($(me.getImage()._peer._native), { + title: $msg('NOTE'), + container: 'body', + // Content can also be a function of the target element! + content() { + return me._buildTooltipContent(); + }, + html: true, + placement: 'bottom', + destroyOnExit: true, + }); + }, + + _buildTooltipContent() { + if ($('body').find('#textPopoverNote').length == 1) { + var text = $('body').find('#textPopoverNote'); + text.text(this._linksModel.getText()); + } else { + const result = $('
').css({ padding: '5px' }); + + var text = $('
').text(this._linksModel.getText()) + .css({ + 'white-space': 'pre-wrap', + 'word-wrap': 'break-word', + }); + result.append(text); + return result; + } + }, + + getModel() { + return this._linksModel; + }, }); -NoteIcon.IMAGE_URL = "images/notes.png"; +NoteIcon.IMAGE_URL = 'images/notes.png'; -export default NoteIcon +export default NoteIcon; diff --git a/packages/mindplot/lib/components/Options.js b/packages/mindplot/lib/components/Options.js index 9312acff..1f41926d 100644 --- a/packages/mindplot/lib/components/Options.js +++ b/packages/mindplot/lib/components/Options.js @@ -1,14 +1,16 @@ const Options = new Class({ - setOptions: function () { - var options = this.options = Object.merge.apply(null, [{}, this.options].append(arguments)); - if (this.addEvent) for (var option in options) { - if (typeOf(options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue; - this.addEvent(option, options[option]); - delete options[option]; - } - return this; + setOptions() { + const options = this.options = Object.merge.apply(null, [{}, this.options].append(arguments)); + if (this.addEvent) { + for (const option in options) { + if (typeOf(options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue; + this.addEvent(option, options[option]); + delete options[option]; + } } + return this; + }, }); diff --git a/packages/mindplot/lib/components/PersistenceManager.js b/packages/mindplot/lib/components/PersistenceManager.js index 1e3ef269..b3e3ceba 100644 --- a/packages/mindplot/lib/components/PersistenceManager.js +++ b/packages/mindplot/lib/components/PersistenceManager.js @@ -16,71 +16,72 @@ * limitations under the License. */ const Core = require('@wismapping/core-js'); + const core = Core(); const XMLSerializerFactory = require('./persistence/XMLSerializerFactory'); const PersistenceManager = new Class({ - Static: { - loadFromDom: function (mapId, mapDom) { - $assert(mapId, 'mapId can not be null'); - $assert(mapDom, 'mapDom can not be null'); + Static: { + loadFromDom(mapId, mapDom) { + $assert(mapId, 'mapId can not be null'); + $assert(mapDom, 'mapDom can not be null'); - var serializer = XMLSerializerFactory.getSerializerFromDocument(mapDom); - return serializer.loadFromDom(mapDom, mapId); - }, + const serializer = XMLSerializerFactory.getSerializerFromDocument(mapDom); + return serializer.loadFromDom(mapDom, mapId); }, + }, - initialize: function () {}, + initialize() {}, - save: function (mindmap, editorProperties, saveHistory, events, sync) { - $assert(mindmap, 'mindmap can not be null'); - $assert(editorProperties, 'editorProperties can not be null'); + save(mindmap, editorProperties, saveHistory, events, sync) { + $assert(mindmap, 'mindmap can not be null'); + $assert(editorProperties, 'editorProperties can not be null'); - var mapId = mindmap.getId(); - $assert(mapId, 'mapId can not be null'); + const mapId = mindmap.getId(); + $assert(mapId, 'mapId can not be null'); - var serializer = XMLSerializerFactory.getSerializerFromMindmap(mindmap); - var domMap = serializer.toXML(mindmap); - var mapXml = core.Utils.innerXML(domMap); + const serializer = XMLSerializerFactory.getSerializerFromMindmap(mindmap); + const domMap = serializer.toXML(mindmap); + const mapXml = core.Utils.innerXML(domMap); - var pref = JSON.stringify(editorProperties); - try { - this.saveMapXml(mapId, mapXml, pref, saveHistory, events, sync); - } catch (e) { - console.log(e); - events.onError(this._buildError()); - } - }, + const pref = JSON.stringify(editorProperties); + try { + this.saveMapXml(mapId, mapXml, pref, saveHistory, events, sync); + } catch (e) { + console.log(e); + events.onError(this._buildError()); + } + }, - load: function (mapId) { - $assert(mapId, 'mapId can not be null'); - var domDocument = this.loadMapDom(mapId); - return PersistenceManager.loadFromDom(mapId, domDocument); - }, + load(mapId) { + $assert(mapId, 'mapId can not be null'); + const domDocument = this.loadMapDom(mapId); + return PersistenceManager.loadFromDom(mapId, domDocument); + }, - discardChanges: function (mapId) { - throw new Error('Method must be implemented'); - }, + discardChanges(mapId) { + throw new Error('Method must be implemented'); + }, - loadMapDom: function (mapId) { - throw new Error('Method must be implemented'); - }, + loadMapDom(mapId) { + throw new Error('Method must be implemented'); + }, - saveMapXml: function (mapId, mapXml, pref, saveHistory, events, sync) { - throw new Error('Method must be implemented'); - }, + saveMapXml(mapId, mapXml, pref, saveHistory, events, sync) { + throw new Error('Method must be implemented'); + }, - unlockMap: function (mindmap) { - throw new Error('Method must be implemented'); - }, + unlockMap(mindmap) { + throw new Error('Method must be implemented'); + }, }); PersistenceManager.init = function (instance) { - PersistenceManager._instance = instance; + PersistenceManager._instance = instance; }; PersistenceManager.getInstance = function () { - return PersistenceManager._instance; + return PersistenceManager._instance; }; export default PersistenceManager; diff --git a/packages/mindplot/lib/components/Relationship.js b/packages/mindplot/lib/components/Relationship.js index 95cef0c8..a587fe03 100644 --- a/packages/mindplot/lib/components/Relationship.js +++ b/packages/mindplot/lib/components/Relationship.js @@ -15,10 +15,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const Core = require('@wismapping/core-js') +const Core = require('@wismapping/core-js'); + const core = Core(); -const web2D = require('@wismapping/web2d') +const web2D = require('@wismapping/web2d'); + const web2d = web2D(); const ConnectionLine = require('./ConnectionLine').default; @@ -26,320 +28,310 @@ const ControlPoint = require('./ControlPoint').default; const INodeModel = require('./model/INodeModel').default; -const Shape = require('./util/Shape').default +const Shape = require('./util/Shape').default; const Relationship = new Class({ - Extends: ConnectionLine, - Static: { - getStrokeColor: function () { - return '#9b74e6'; - }, - type: "Relationship" + Extends: ConnectionLine, + Static: { + getStrokeColor() { + return '#9b74e6'; }, - initialize: function (sourceNode, targetNode, model) { - $assert(sourceNode, "sourceNode can not be null"); - $assert(targetNode, "targetNode can not be null"); + type: 'Relationship', + }, + initialize(sourceNode, targetNode, model) { + $assert(sourceNode, 'sourceNode can not be null'); + $assert(targetNode, 'targetNode can not be null'); - this.parent(sourceNode, targetNode, model.getLineType()); - this.setModel(model); + this.parent(sourceNode, targetNode, model.getLineType()); + this.setModel(model); - var strokeColor = Relationship.getStrokeColor(); + const strokeColor = Relationship.getStrokeColor(); - this._line2d.setIsSrcControlPointCustom(false); - this._line2d.setIsDestControlPointCustom(false); - this._line2d.setCursor('pointer'); - this._line2d.setStroke(1, 'solid', strokeColor); - this._line2d.setDashed(4, 2); - this._focusShape = this._createLine(this.getLineType(), ConnectionLine.SIMPLE_CURVED); - this._focusShape.setStroke(2, "solid", "#3f96ff"); + this._line2d.setIsSrcControlPointCustom(false); + this._line2d.setIsDestControlPointCustom(false); + this._line2d.setCursor('pointer'); + this._line2d.setStroke(1, 'solid', strokeColor); + this._line2d.setDashed(4, 2); + this._focusShape = this._createLine(this.getLineType(), ConnectionLine.SIMPLE_CURVED); + this._focusShape.setStroke(2, 'solid', '#3f96ff'); - var ctrlPoints = this._line2d.getControlPoints(); - this._focusShape.setSrcControlPoint(ctrlPoints[0]); - this._focusShape.setDestControlPoint(ctrlPoints[1]); - this._focusShape.setVisibility(false); - this._onFocus = false; - this._isInWorkspace = false; - this._controlPointsController = new ControlPoint(); + const ctrlPoints = this._line2d.getControlPoints(); + this._focusShape.setSrcControlPoint(ctrlPoints[0]); + this._focusShape.setDestControlPoint(ctrlPoints[1]); + this._focusShape.setVisibility(false); + this._onFocus = false; + this._isInWorkspace = false; + this._controlPointsController = new ControlPoint(); - this._startArrow = new web2d.Arrow(); - this._startArrow.setStrokeColor(strokeColor); - this._startArrow.setStrokeWidth(2); - this.setShowStartArrow(true); + this._startArrow = new web2d.Arrow(); + this._startArrow.setStrokeColor(strokeColor); + this._startArrow.setStrokeWidth(2); + this.setShowStartArrow(true); - // Share style is disable ... - if (this._showEndArrow) { - this._endArrow = new web2d.Arrow(); - this._endArrow.setStrokeColor(strokeColor); - this._endArrow.setStrokeWidth(2); - } - - // Position the line ... - if ($defined(model.getSrcCtrlPoint())) { - var srcPoint = model.getSrcCtrlPoint().clone(); - this.setSrcControlPoint(srcPoint); - } - if ($defined(model.getDestCtrlPoint())) { - var destPoint = model.getDestCtrlPoint().clone(); - this.setDestControlPoint(destPoint); - } - }, - - setStroke: function (color, style, opacity) { - this.parent(color, style, opacity); - this._startArrow.setStrokeColor(color); - }, - - redraw: function () { - var line2d = this._line2d; - var sourceTopic = this._sourceTopic; - var sourcePosition = sourceTopic.getPosition(); - - var targetTopic = this._targetTopic; - var targetPosition = targetTopic.getPosition(); - if (targetTopic.getType() == INodeModel.CENTRAL_TOPIC_TYPE) { - targetPosition = Shape.workoutIncomingConnectionPoint(targetTopic, sourcePosition); - } - - var sPos, tPos; - this._line2d.setStroke(2); - var ctrlPoints = this._line2d.getControlPoints(); - if (!this._line2d.isDestControlPointCustom() && !this._line2d.isSrcControlPointCustom()) { - - var defaultPoints = Shape.calculateDefaultControlPoints(sourcePosition, targetPosition); - ctrlPoints[0].x = defaultPoints[0].x; - ctrlPoints[0].y = defaultPoints[0].y; - - ctrlPoints[1].x = defaultPoints[1].x; - ctrlPoints[1].y = defaultPoints[1].y; - } - var spoint = new core.Point(); - spoint.x = parseInt(ctrlPoints[0].x) + parseInt(sourcePosition.x); - spoint.y = parseInt(ctrlPoints[0].y) + parseInt(sourcePosition.y); - - var tpoint = new core.Point(); - tpoint.x = parseInt(ctrlPoints[1].x) + parseInt(targetPosition.x); - tpoint.y = parseInt(ctrlPoints[1].y) + parseInt(targetPosition.y); - - sPos = Shape.calculateRelationShipPointCoordinates(sourceTopic, spoint); - tPos = Shape.calculateRelationShipPointCoordinates(targetTopic, tpoint); - - line2d.setFrom(sPos.x, sPos.y); - line2d.setTo(tPos.x, tPos.y); - - line2d.moveToFront(); - - //Positionate Arrows - this._positionArrows(); - - // Add connector ... - this._positionateConnector(targetTopic); - - if (this.isOnFocus()) { - this._refreshShape(); - } - this._focusShape.moveToBack(); - this._controlPointsController.redraw(); - }, - - _positionArrows: function () { - var tpos = this._line2d.getTo(); - var spos = this._line2d.getFrom(); - - this._startArrow.setFrom(spos.x, spos.y); - this._startArrow.moveToBack(); - - if (this._endArrow) { - this._endArrow.setFrom(tpos.x, tpos.y); - this._endArrow.moveToBack(); - } - - if (this._line2d.getType() == "CurvedLine") { - var controlPoints = this._line2d.getControlPoints(); - this._startArrow.setControlPoint(controlPoints[0]); - if (this._endArrow) { - this._endArrow.setControlPoint(controlPoints[1]); - } - } else { - this._startArrow.setControlPoint(this._line2d.getTo()); - if (this._endArrow) { - this._endArrow.setControlPoint(this._line2d.getFrom()); - } - } - - if (this._showEndArrow) { - this._endArrow.setVisibility(this.isVisible()); - } - this._startArrow.setVisibility(this.isVisible() && this._showStartArrow); - }, - - addToWorkspace: function (workspace) { - workspace.append(this._focusShape); - workspace.append(this._controlPointsController); - - this._controlPointControllerListener = this._initializeControlPointController.bind(this); - this._line2d.addEvent('click', this._controlPointControllerListener); - this._isInWorkspace = true; - - workspace.append(this._startArrow); - if (this._endArrow) - workspace.append(this._endArrow); - - this.parent(workspace); - this._positionArrows(); - this.redraw(); - - }, - - _initializeControlPointController: function () { - this.setOnFocus(true); - }, - - removeFromWorkspace: function (workspace) { - workspace.removeChild(this._focusShape); - workspace.removeChild(this._controlPointsController); - this._line2d.removeEvent('click', this._controlPointControllerListener); - this._isInWorkspace = false; - workspace.removeChild(this._startArrow); - if (this._endArrow) - workspace.removeChild(this._endArrow); - - this.parent(workspace); - }, - - getType: function () { - return Relationship.type; - }, - - setOnFocus: function (focus) { - // Change focus shape - if (this.isOnFocus() != focus) { - if (focus) { - this._refreshShape(); - this._controlPointsController.setLine(this); - } - this._focusShape.setVisibility(focus); - - this._controlPointsController.setVisibility(focus); - this._onFocus = focus; - this.fireEvent(focus ? 'ontfocus' : 'ontblur', this); - } - }, - - _refreshShape: function () { - var sPos = this._line2d.getFrom(); - var tPos = this._line2d.getTo(); - var ctrlPoints = this._line2d.getControlPoints(); - this._focusShape.setFrom(sPos.x, sPos.y); - this._focusShape.setTo(tPos.x, tPos.y); - var shapeCtrlPoints = this._focusShape.getControlPoints(); - shapeCtrlPoints[0].x = ctrlPoints[0].x; - shapeCtrlPoints[0].y = ctrlPoints[0].y; - shapeCtrlPoints[1].x = ctrlPoints[1].x; - shapeCtrlPoints[1].y = ctrlPoints[1].y; - this._focusShape.updateLine(); - }, - - addEvent: function (type, listener) { - // Translate to web 2d events ... - if (type == 'onfocus') { - type = 'mousedown'; - } - - var line = this._line2d; - line.addEvent(type, listener); - }, - - isOnFocus: function () { - return this._onFocus; - }, - - isInWorkspace: function () { - return this._isInWorkspace; - }, - - setVisibility: function (value) { - this.parent(value); - if (this._showEndArrow) - this._endArrow.setVisibility(this._showEndArrow); - this._startArrow.setVisibility(this._showStartArrow && value); - }, - - setOpacity: function (opacity) { - this.parent(opacity); - if (this._showEndArrow) - this._endArrow.setOpacity(opacity); - if (this._showStartArrow) - this._startArrow.setOpacity(opacity); - }, - - setShowEndArrow: function (visible) { - this._showEndArrow = visible; - if (this._isInWorkspace) - this.redraw(); - }, - - setShowStartArrow: function (visible) { - this._showStartArrow = visible; - if (this._isInWorkspace) - this.redraw(); - }, - - setFrom: function (x, y) { - $assert($defined(x), "x must be defined"); - $assert($defined(y), "y must be defined"); - - this._line2d.setFrom(x, y); - this._startArrow.setFrom(x, y); - }, - - setTo: function (x, y) { - $assert($defined(x), "x must be defined"); - $assert($defined(y), "y must be defined"); - - this._line2d.setTo(x, y); - if (this._endArrow) - this._endArrow.setFrom(x, y); - }, - - setSrcControlPoint: function (control) { - this._line2d.setSrcControlPoint(control); - this._startArrow.setControlPoint(control); - }, - - setDestControlPoint: function (control) { - this._line2d.setDestControlPoint(control); - if (this._showEndArrow) - this._endArrow.setControlPoint(control); - }, - - getControlPoints: function () { - return this._line2d.getControlPoints(); - }, - - isSrcControlPointCustom: function () { - return this._line2d.isSrcControlPointCustom(); - }, - - isDestControlPointCustom: function () { - return this._line2d.isDestControlPointCustom(); - }, - - setIsSrcControlPointCustom: function (isCustom) { - this._line2d.setIsSrcControlPointCustom(isCustom); - }, - - setIsDestControlPointCustom: function (isCustom) { - this._line2d.setIsDestControlPointCustom(isCustom); - }, - - getId: function () { - return this._model.getId(); - }, - - fireEvent: function (type, event) { - var elem = this._line2d; - elem.trigger(type, event); + // Share style is disable ... + if (this._showEndArrow) { + this._endArrow = new web2d.Arrow(); + this._endArrow.setStrokeColor(strokeColor); + this._endArrow.setStrokeWidth(2); } + + // Position the line ... + if ($defined(model.getSrcCtrlPoint())) { + const srcPoint = model.getSrcCtrlPoint().clone(); + this.setSrcControlPoint(srcPoint); + } + if ($defined(model.getDestCtrlPoint())) { + const destPoint = model.getDestCtrlPoint().clone(); + this.setDestControlPoint(destPoint); + } + }, + + setStroke(color, style, opacity) { + this.parent(color, style, opacity); + this._startArrow.setStrokeColor(color); + }, + + redraw() { + const line2d = this._line2d; + const sourceTopic = this._sourceTopic; + const sourcePosition = sourceTopic.getPosition(); + + const targetTopic = this._targetTopic; + let targetPosition = targetTopic.getPosition(); + if (targetTopic.getType() == INodeModel.CENTRAL_TOPIC_TYPE) { + targetPosition = Shape.workoutIncomingConnectionPoint(targetTopic, sourcePosition); + } + + let sPos; let + tPos; + this._line2d.setStroke(2); + const ctrlPoints = this._line2d.getControlPoints(); + if (!this._line2d.isDestControlPointCustom() && !this._line2d.isSrcControlPointCustom()) { + const defaultPoints = Shape.calculateDefaultControlPoints(sourcePosition, targetPosition); + ctrlPoints[0].x = defaultPoints[0].x; + ctrlPoints[0].y = defaultPoints[0].y; + + ctrlPoints[1].x = defaultPoints[1].x; + ctrlPoints[1].y = defaultPoints[1].y; + } + const spoint = new core.Point(); + spoint.x = parseInt(ctrlPoints[0].x) + parseInt(sourcePosition.x); + spoint.y = parseInt(ctrlPoints[0].y) + parseInt(sourcePosition.y); + + const tpoint = new core.Point(); + tpoint.x = parseInt(ctrlPoints[1].x) + parseInt(targetPosition.x); + tpoint.y = parseInt(ctrlPoints[1].y) + parseInt(targetPosition.y); + + sPos = Shape.calculateRelationShipPointCoordinates(sourceTopic, spoint); + tPos = Shape.calculateRelationShipPointCoordinates(targetTopic, tpoint); + + line2d.setFrom(sPos.x, sPos.y); + line2d.setTo(tPos.x, tPos.y); + + line2d.moveToFront(); + + // Positionate Arrows + this._positionArrows(); + + // Add connector ... + this._positionateConnector(targetTopic); + + if (this.isOnFocus()) { + this._refreshShape(); + } + this._focusShape.moveToBack(); + this._controlPointsController.redraw(); + }, + + _positionArrows() { + const tpos = this._line2d.getTo(); + const spos = this._line2d.getFrom(); + + this._startArrow.setFrom(spos.x, spos.y); + this._startArrow.moveToBack(); + + if (this._endArrow) { + this._endArrow.setFrom(tpos.x, tpos.y); + this._endArrow.moveToBack(); + } + + if (this._line2d.getType() == 'CurvedLine') { + const controlPoints = this._line2d.getControlPoints(); + this._startArrow.setControlPoint(controlPoints[0]); + if (this._endArrow) { + this._endArrow.setControlPoint(controlPoints[1]); + } + } else { + this._startArrow.setControlPoint(this._line2d.getTo()); + if (this._endArrow) { + this._endArrow.setControlPoint(this._line2d.getFrom()); + } + } + + if (this._showEndArrow) { + this._endArrow.setVisibility(this.isVisible()); + } + this._startArrow.setVisibility(this.isVisible() && this._showStartArrow); + }, + + addToWorkspace(workspace) { + workspace.append(this._focusShape); + workspace.append(this._controlPointsController); + + this._controlPointControllerListener = this._initializeControlPointController.bind(this); + this._line2d.addEvent('click', this._controlPointControllerListener); + this._isInWorkspace = true; + + workspace.append(this._startArrow); + if (this._endArrow) workspace.append(this._endArrow); + + this.parent(workspace); + this._positionArrows(); + this.redraw(); + }, + + _initializeControlPointController() { + this.setOnFocus(true); + }, + + removeFromWorkspace(workspace) { + workspace.removeChild(this._focusShape); + workspace.removeChild(this._controlPointsController); + this._line2d.removeEvent('click', this._controlPointControllerListener); + this._isInWorkspace = false; + workspace.removeChild(this._startArrow); + if (this._endArrow) workspace.removeChild(this._endArrow); + + this.parent(workspace); + }, + + getType() { + return Relationship.type; + }, + + setOnFocus(focus) { + // Change focus shape + if (this.isOnFocus() != focus) { + if (focus) { + this._refreshShape(); + this._controlPointsController.setLine(this); + } + this._focusShape.setVisibility(focus); + + this._controlPointsController.setVisibility(focus); + this._onFocus = focus; + this.fireEvent(focus ? 'ontfocus' : 'ontblur', this); + } + }, + + _refreshShape() { + const sPos = this._line2d.getFrom(); + const tPos = this._line2d.getTo(); + const ctrlPoints = this._line2d.getControlPoints(); + this._focusShape.setFrom(sPos.x, sPos.y); + this._focusShape.setTo(tPos.x, tPos.y); + const shapeCtrlPoints = this._focusShape.getControlPoints(); + shapeCtrlPoints[0].x = ctrlPoints[0].x; + shapeCtrlPoints[0].y = ctrlPoints[0].y; + shapeCtrlPoints[1].x = ctrlPoints[1].x; + shapeCtrlPoints[1].y = ctrlPoints[1].y; + this._focusShape.updateLine(); + }, + + addEvent(type, listener) { + // Translate to web 2d events ... + if (type == 'onfocus') { + type = 'mousedown'; + } + + const line = this._line2d; + line.addEvent(type, listener); + }, + + isOnFocus() { + return this._onFocus; + }, + + isInWorkspace() { + return this._isInWorkspace; + }, + + setVisibility(value) { + this.parent(value); + if (this._showEndArrow) this._endArrow.setVisibility(this._showEndArrow); + this._startArrow.setVisibility(this._showStartArrow && value); + }, + + setOpacity(opacity) { + this.parent(opacity); + if (this._showEndArrow) this._endArrow.setOpacity(opacity); + if (this._showStartArrow) this._startArrow.setOpacity(opacity); + }, + + setShowEndArrow(visible) { + this._showEndArrow = visible; + if (this._isInWorkspace) this.redraw(); + }, + + setShowStartArrow(visible) { + this._showStartArrow = visible; + if (this._isInWorkspace) this.redraw(); + }, + + setFrom(x, y) { + $assert($defined(x), 'x must be defined'); + $assert($defined(y), 'y must be defined'); + + this._line2d.setFrom(x, y); + this._startArrow.setFrom(x, y); + }, + + setTo(x, y) { + $assert($defined(x), 'x must be defined'); + $assert($defined(y), 'y must be defined'); + + this._line2d.setTo(x, y); + if (this._endArrow) this._endArrow.setFrom(x, y); + }, + + setSrcControlPoint(control) { + this._line2d.setSrcControlPoint(control); + this._startArrow.setControlPoint(control); + }, + + setDestControlPoint(control) { + this._line2d.setDestControlPoint(control); + if (this._showEndArrow) this._endArrow.setControlPoint(control); + }, + + getControlPoints() { + return this._line2d.getControlPoints(); + }, + + isSrcControlPointCustom() { + return this._line2d.isSrcControlPointCustom(); + }, + + isDestControlPointCustom() { + return this._line2d.isDestControlPointCustom(); + }, + + setIsSrcControlPointCustom(isCustom) { + this._line2d.setIsSrcControlPointCustom(isCustom); + }, + + setIsDestControlPointCustom(isCustom) { + this._line2d.setIsDestControlPointCustom(isCustom); + }, + + getId() { + return this._model.getId(); + }, + + fireEvent(type, event) { + const elem = this._line2d; + elem.trigger(type, event); + }, }); export default Relationship; diff --git a/packages/mindplot/lib/components/RelationshipPivot.js b/packages/mindplot/lib/components/RelationshipPivot.js index 429493b5..b597e93e 100644 --- a/packages/mindplot/lib/components/RelationshipPivot.js +++ b/packages/mindplot/lib/components/RelationshipPivot.js @@ -15,153 +15,151 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const Core = require('@wismapping/core-js') +const Core = require('@wismapping/core-js'); + const core = Core(); -const web2D = require('@wismapping/web2d') +const web2D = require('@wismapping/web2d'); + const web2d = web2D(); -const INodeModel = require('./model/INodeModel').default +const INodeModel = require('./model/INodeModel').default; const Shape = require('./util/Shape').default; const RelationshipPivot = new Class({ - initialize: function (workspace, designer) { - $assert(workspace, "workspace can not be null"); - $assert(designer, "designer can not be null"); - this._workspace = workspace; - this._designer = designer; + initialize(workspace, designer) { + $assert(workspace, 'workspace can not be null'); + $assert(designer, 'designer can not be null'); + this._workspace = workspace; + this._designer = designer; - //FIXME: the aim of the migration is remove .bind mootools method, please remove these! - this._mouseMoveEvent = this._mouseMove.bind(this); - this._onClickEvent = this._cleanOnMouseClick.bind(this); - this._onTopicClick = this._connectOnFocus.bind(this); + // FIXME: the aim of the migration is remove .bind mootools method, please remove these! + this._mouseMoveEvent = this._mouseMove.bind(this); + this._onClickEvent = this._cleanOnMouseClick.bind(this); + this._onTopicClick = this._connectOnFocus.bind(this); + }, - }, + start(sourceTopic, targetPos) { + $assert(sourceTopic, 'sourceTopic can not be null'); + $assert(targetPos, 'targetPos can not be null'); - start: function (sourceTopic, targetPos) { - $assert(sourceTopic, "sourceTopic can not be null"); - $assert(targetPos, "targetPos can not be null"); + this.dispose(); + this._sourceTopic = sourceTopic; + if (sourceTopic != null) { + this._workspace.enableWorkspaceEvents(false); - this.dispose(); - this._sourceTopic = sourceTopic; - if (sourceTopic != null) { - this._workspace.enableWorkspaceEvents(false); + const sourcePos = sourceTopic.getPosition(); + const strokeColor = Relationship.getStrokeColor(); - var sourcePos = sourceTopic.getPosition(); - var strokeColor = Relationship.getStrokeColor(); + this._pivot = new web2d.CurvedLine(); + this._pivot.setStyle(web2d.CurvedLine.SIMPLE_LINE); - this._pivot = new web2d.CurvedLine(); - this._pivot.setStyle(web2d.CurvedLine.SIMPLE_LINE); + const fromPos = this._calculateFromPosition(sourcePos); + this._pivot.setFrom(fromPos.x, fromPos.y); - var fromPos = this._calculateFromPosition(sourcePos); - this._pivot.setFrom(fromPos.x, fromPos.y); + this._pivot.setTo(targetPos.x, targetPos.y); + this._pivot.setStroke(2, 'solid', strokeColor); + this._pivot.setDashed(4, 2); - this._pivot.setTo(targetPos.x, targetPos.y); - this._pivot.setStroke(2, 'solid', strokeColor); - this._pivot.setDashed(4, 2); + this._startArrow = new web2d.Arrow(); + this._startArrow.setStrokeColor(strokeColor); + this._startArrow.setStrokeWidth(2); + this._startArrow.setFrom(sourcePos.x, sourcePos.y); - this._startArrow = new web2d.Arrow(); - this._startArrow.setStrokeColor(strokeColor); - this._startArrow.setStrokeWidth(2); - this._startArrow.setFrom(sourcePos.x, sourcePos.y); + this._workspace.append(this._pivot); + this._workspace.append(this._startArrow); - this._workspace.append(this._pivot); - this._workspace.append(this._startArrow); + this._workspace.addEvent('mousemove', this._mouseMoveEvent); + this._workspace.addEvent('click', this._onClickEvent); - this._workspace.addEvent('mousemove', this._mouseMoveEvent); - this._workspace.addEvent('click', this._onClickEvent); - - // Register focus events on all topics ... - var model = this._designer.getModel(); - var topics = model.getTopics(); - _.each(topics, function (topic) { - topic.addEvent('ontfocus', this._onTopicClick); - }.bind(this)); - } - - }, - - dispose: function () { - var workspace = this._workspace; - - if (this._isActive()) { - workspace.removeEvent('mousemove', this._mouseMoveEvent); - workspace.removeEvent('click', this._onClickEvent); - - var model = this._designer.getModel(); - var topics = model.getTopics(); - var me = this; - _.each(topics, function (topic) { - topic.removeEvent('ontfocus', me._onTopicClick); - }); - - workspace.removeChild(this._pivot); - workspace.removeChild(this._startArrow); - workspace.enableWorkspaceEvents(true); - - this._sourceTopic = null; - this._pivot = null; - this._startArrow = null; - } - }, - - _mouseMove: function (event) { - var screen = this._workspace.getScreenManager(); - var pos = screen.getWorkspaceMousePosition(event); - - // Leave the arrow a couple of pixels away from the cursor. - var sourcePosition = this._sourceTopic.getPosition(); - var gapDistance = Math.sign(pos.x - sourcePosition.x) * 5; - - var sPos = this._calculateFromPosition(pos); - this._pivot.setFrom(sPos.x, sPos.y); - - // Update target position ... - this._pivot.setTo(pos.x - gapDistance, pos.y); - - var controlPoints = this._pivot.getControlPoints(); - this._startArrow.setFrom(pos.x - gapDistance, pos.y); - this._startArrow.setControlPoint(controlPoints[1]); - - event.stopPropagation(); - return false; - }, - - _cleanOnMouseClick: function (event) { - - // The user clicks on a desktop on in other element that is not a node. - this.dispose(); - event.stopPropagation(); - }, - - _calculateFromPosition: function (toPosition) { - - // Calculate origin position ... - var sourcePosition = this._sourceTopic.getPosition(); - if (this._sourceTopic.getType() == INodeModel.CENTRAL_TOPIC_TYPE) { - sourcePosition = Shape.workoutIncomingConnectionPoint(this._sourceTopic, toPosition); - } - var controlPoint = Shape.calculateDefaultControlPoints(sourcePosition, toPosition); - - var spoint = new core.Point(); - spoint.x = parseInt(controlPoint[0].x) + parseInt(sourcePosition.x); - spoint.y = parseInt(controlPoint[0].y) + parseInt(sourcePosition.y); - return Shape.calculateRelationShipPointCoordinates(this._sourceTopic, spoint); - }, - - _connectOnFocus: function (event, targetTopic) { - var sourceTopic = this._sourceTopic; - var mindmap = this._designer.getMindmap(); - - // Avoid circular connections ... - if (targetTopic.getId() != sourceTopic.getId()) { - var relModel = mindmap.createRelationship(targetTopic.getId(), sourceTopic.getId()); - this._designer._actionDispatcher.addRelationship(relModel); - } - this.dispose(); - }, - - _isActive: function () { - return this._pivot != null; + // Register focus events on all topics ... + const model = this._designer.getModel(); + const topics = model.getTopics(); + _.each(topics, (topic) => { + topic.addEvent('ontfocus', this._onTopicClick); + }); } + }, + + dispose() { + const workspace = this._workspace; + + if (this._isActive()) { + workspace.removeEvent('mousemove', this._mouseMoveEvent); + workspace.removeEvent('click', this._onClickEvent); + + const model = this._designer.getModel(); + const topics = model.getTopics(); + const me = this; + _.each(topics, (topic) => { + topic.removeEvent('ontfocus', me._onTopicClick); + }); + + workspace.removeChild(this._pivot); + workspace.removeChild(this._startArrow); + workspace.enableWorkspaceEvents(true); + + this._sourceTopic = null; + this._pivot = null; + this._startArrow = null; + } + }, + + _mouseMove(event) { + const screen = this._workspace.getScreenManager(); + const pos = screen.getWorkspaceMousePosition(event); + + // Leave the arrow a couple of pixels away from the cursor. + const sourcePosition = this._sourceTopic.getPosition(); + const gapDistance = Math.sign(pos.x - sourcePosition.x) * 5; + + const sPos = this._calculateFromPosition(pos); + this._pivot.setFrom(sPos.x, sPos.y); + + // Update target position ... + this._pivot.setTo(pos.x - gapDistance, pos.y); + + const controlPoints = this._pivot.getControlPoints(); + this._startArrow.setFrom(pos.x - gapDistance, pos.y); + this._startArrow.setControlPoint(controlPoints[1]); + + event.stopPropagation(); + return false; + }, + + _cleanOnMouseClick(event) { + // The user clicks on a desktop on in other element that is not a node. + this.dispose(); + event.stopPropagation(); + }, + + _calculateFromPosition(toPosition) { + // Calculate origin position ... + let sourcePosition = this._sourceTopic.getPosition(); + if (this._sourceTopic.getType() == INodeModel.CENTRAL_TOPIC_TYPE) { + sourcePosition = Shape.workoutIncomingConnectionPoint(this._sourceTopic, toPosition); + } + const controlPoint = Shape.calculateDefaultControlPoints(sourcePosition, toPosition); + + const spoint = new core.Point(); + spoint.x = parseInt(controlPoint[0].x) + parseInt(sourcePosition.x); + spoint.y = parseInt(controlPoint[0].y) + parseInt(sourcePosition.y); + return Shape.calculateRelationShipPointCoordinates(this._sourceTopic, spoint); + }, + + _connectOnFocus(event, targetTopic) { + const sourceTopic = this._sourceTopic; + const mindmap = this._designer.getMindmap(); + + // Avoid circular connections ... + if (targetTopic.getId() != sourceTopic.getId()) { + const relModel = mindmap.createRelationship(targetTopic.getId(), sourceTopic.getId()); + this._designer._actionDispatcher.addRelationship(relModel); + } + this.dispose(); + }, + + _isActive() { + return this._pivot != null; + }, }); export default RelationshipPivot; diff --git a/packages/mindplot/lib/components/RestPersistenceManager.js b/packages/mindplot/lib/components/RestPersistenceManager.js index 7ff23522..d5795c83 100644 --- a/packages/mindplot/lib/components/RestPersistenceManager.js +++ b/packages/mindplot/lib/components/RestPersistenceManager.js @@ -18,149 +18,142 @@ const PersistenceManager = require('./PersistenceManager').default; const RESTPersistenceManager = new Class({ - Extends: PersistenceManager, - initialize: function (options) { - this.parent(); - $assert(options.documentUrl, "documentUrl can not be null"); - $assert(options.revertUrl, "revertUrl can not be null"); - $assert(options.lockUrl, "lockUrl can not be null"); - $assert(options.session, "session can not be null"); - $assert(options.timestamp, "timestamp can not be null"); + Extends: PersistenceManager, + initialize(options) { + this.parent(); + $assert(options.documentUrl, 'documentUrl can not be null'); + $assert(options.revertUrl, 'revertUrl can not be null'); + $assert(options.lockUrl, 'lockUrl can not be null'); + $assert(options.session, 'session can not be null'); + $assert(options.timestamp, 'timestamp can not be null'); - this.documentUrl = options.documentUrl; - this.revertUrl = options.revertUrl; - this.lockUrl = options.lockUrl; - this.timestamp = options.timestamp; - this.session = options.session; + this.documentUrl = options.documentUrl; + this.revertUrl = options.revertUrl; + this.lockUrl = options.lockUrl; + this.timestamp = options.timestamp; + this.session = options.session; + }, + + saveMapXml(mapId, mapXml, pref, saveHistory, events, sync) { + const data = { + id: mapId, + xml: mapXml, + properties: pref, + }; + + const persistence = this; + let query = `minor=${!saveHistory}`; + query = `${query}×tamp=${this.timestamp}`; + query = `${query}&session=${this.session}`; + + if (!persistence.onSave) { + // Mark save in process and fire a event unlocking the save ... + persistence.onSave = true; + persistence.clearTimeout = setTimeout(() => { + persistence.clearTimeout = null; + persistence.onSave = false; + }, 10000); + + $.ajax({ + url: `${this.documentUrl.replace('{id}', mapId)}?${query}`, + type: 'put', + dataType: 'json', + data: JSON.stringify(data), + contentType: 'application/json; charset=utf-8', + async: !sync, + + success(data, textStatus, jqXHRresponseText) { + persistence.timestamp = data; + events.onSuccess(); }, + error(jqXHR, textStatus, errorThrown) { + events.onError(persistence._buildError()); + }, + complete() { + // Clear event timeout ... + if (persistence.clearTimeout) { + clearTimeout(persistence.clearTimeout); + } + persistence.onSave = false; + }, + fail(xhr, textStatus) { + const { responseText } = xhr; + let userMsg = { severity: 'SEVERE', message: $msg('SAVE_COULD_NOT_BE_COMPLETED') }; - saveMapXml: function (mapId, mapXml, pref, saveHistory, events, sync) { - - var data = { - id: mapId, - xml: mapXml, - properties: pref - }; - - var persistence = this; - var query = "minor=" + !saveHistory; - query = query + "×tamp=" + this.timestamp; - query = query + "&session=" + this.session; - - if (!persistence.onSave) { - - // Mark save in process and fire a event unlocking the save ... - persistence.onSave = true; - persistence.clearTimeout = setTimeout(function () { - persistence.clearTimeout = null; - persistence.onSave = false; - }, 10000); - - $.ajax({ - url: this.documentUrl.replace("{id}", mapId) + "?" + query, - type: 'put', - dataType: "json", - data: JSON.stringify(data), - contentType: "application/json; charset=utf-8", - async: !sync, - - success: function (data, textStatus, jqXHRresponseText) { - persistence.timestamp = data; - events.onSuccess(); - }, - error: function (jqXHR, textStatus, errorThrown) { - events.onError(persistence._buildError()); - }, - complete: function () { - // Clear event timeout ... - if (persistence.clearTimeout) { - clearTimeout(persistence.clearTimeout); - } - persistence.onSave = false; - }, - fail: function (xhr, textStatus) { - - var responseText = xhr.responseText; - var userMsg = {severity: "SEVERE", message: $msg('SAVE_COULD_NOT_BE_COMPLETED')}; - - var contentType = xhr.getResponseHeader("Content-Type"); - if (contentType != null && contentType.indexOf("application/json") != -1) { - var serverMsg = null; - try { - serverMsg = $.parseJSON(responseText); - serverMsg = serverMsg.globalSeverity ? serverMsg : null; - } catch (e) { - // Message could not be decoded ... - } - userMsg = persistence._buildError(serverMsg); - - } else { - if (this.status == 405) { - userMsg = {severity: "SEVERE", message: $msg('SESSION_EXPIRED')}; - } - } - events.onError(userMsg); - persistence.onSave = false; - } - }); + const contentType = xhr.getResponseHeader('Content-Type'); + if (contentType != null && contentType.indexOf('application/json') != -1) { + let serverMsg = null; + try { + serverMsg = $.parseJSON(responseText); + serverMsg = serverMsg.globalSeverity ? serverMsg : null; + } catch (e) { + // Message could not be decoded ... } + userMsg = persistence._buildError(serverMsg); + } else if (this.status == 405) { + userMsg = { severity: 'SEVERE', message: $msg('SESSION_EXPIRED') }; + } + events.onError(userMsg); + persistence.onSave = false; }, - - discardChanges: function (mapId) { - $.ajax({ - url: this.revertUrl.replace("{id}", mapId), - async: false, - method: 'post', - headers: {"Content-Type": "application/json; charset=utf-8", "Accept": "application/json"} - }); - }, - - unlockMap: function (mindmap) { - var mapId = mindmap.getId(); - $.ajax({ - url: this.lockUrl.replace("{id}", mapId), - async: false, - method: 'put', - headers: {"Content-Type": "text/plain"}, - data: "false" - }); - }, - - _buildError: function (jsonSeverResponse) { - var message = jsonSeverResponse ? jsonSeverResponse.globalErrors[0] : null; - var severity = jsonSeverResponse ? jsonSeverResponse.globalSeverity : null; - - if (!message) { - message = $msg('SAVE_COULD_NOT_BE_COMPLETED'); - } - - if (!severity) { - severity = "INFO"; - } - return {severity: severity, message: message}; - }, - - loadMapDom: function (mapId) { - // Let's try to open one from the local directory ... - var xml; - $.ajax({ - url: this.documentUrl.replace("{id}", mapId) + "/xml", - method: 'get', - async: false, - headers: {"Content-Type": "text/plain", "Accept": "application/xml"}, - success: function (responseText) { - xml = responseText; - } - }); - - // If I could not load it from a file, hard code one. - if (xml == null) { - throw new Error("Map could not be loaded"); - } - - return xml; - } + }); } -); + }, + + discardChanges(mapId) { + $.ajax({ + url: this.revertUrl.replace('{id}', mapId), + async: false, + method: 'post', + headers: { 'Content-Type': 'application/json; charset=utf-8', Accept: 'application/json' }, + }); + }, + + unlockMap(mindmap) { + const mapId = mindmap.getId(); + $.ajax({ + url: this.lockUrl.replace('{id}', mapId), + async: false, + method: 'put', + headers: { 'Content-Type': 'text/plain' }, + data: 'false', + }); + }, + + _buildError(jsonSeverResponse) { + let message = jsonSeverResponse ? jsonSeverResponse.globalErrors[0] : null; + let severity = jsonSeverResponse ? jsonSeverResponse.globalSeverity : null; + + if (!message) { + message = $msg('SAVE_COULD_NOT_BE_COMPLETED'); + } + + if (!severity) { + severity = 'INFO'; + } + return { severity, message }; + }, + + loadMapDom(mapId) { + // Let's try to open one from the local directory ... + let xml; + $.ajax({ + url: `${this.documentUrl.replace('{id}', mapId)}/xml`, + method: 'get', + async: false, + headers: { 'Content-Type': 'text/plain', Accept: 'application/xml' }, + success(responseText) { + xml = responseText; + }, + }); + + // If I could not load it from a file, hard code one. + if (xml == null) { + throw new Error('Map could not be loaded'); + } + + return xml; + }, +}); export default RESTPersistenceManager; diff --git a/packages/mindplot/lib/components/ScreenManager.js b/packages/mindplot/lib/components/ScreenManager.js index 84b3ad91..83c47b2f 100644 --- a/packages/mindplot/lib/components/ScreenManager.js +++ b/packages/mindplot/lib/components/ScreenManager.js @@ -16,138 +16,135 @@ * limitations under the License. */ const Core = require('@wismapping/core-js'); + const core = Core(); const ScreenManager = new Class({ - initialize: function (divElement) { - $assert(divElement, "can not be null"); - this._divContainer = divElement; - this._padding = {x: 0, y: 0}; + initialize(divElement) { + $assert(divElement, 'can not be null'); + this._divContainer = divElement; + this._padding = { x: 0, y: 0 }; - // Ignore default click event propagation. Prevent 'click' event on drag. - this._clickEvents = []; - this._divContainer.bind('click', function (event) { - event.stopPropagation() - }); + // Ignore default click event propagation. Prevent 'click' event on drag. + this._clickEvents = []; + this._divContainer.bind('click', (event) => { + event.stopPropagation(); + }); - this._divContainer.bind('dblclick', function (event) { - event.stopPropagation(); - event.preventDefault(); - }); - }, + this._divContainer.bind('dblclick', (event) => { + event.stopPropagation(); + event.preventDefault(); + }); + }, - setScale: function (scale) { - $assert(scale, 'Screen scale can not be null'); - this._scale = scale; - }, + setScale(scale) { + $assert(scale, 'Screen scale can not be null'); + this._scale = scale; + }, - addEvent: function (event, listener) { - if (event == 'click') - this._clickEvents.push(listener); - else - this._divContainer.bind(event, listener); - }, + addEvent(event, listener) { + if (event == 'click') this._clickEvents.push(listener); + else this._divContainer.bind(event, listener); + }, - removeEvent: function (event, listener) { - if (event == 'click') { - this._clickEvents.remove(listener); - } - else { - this._divContainer.unbind(event, listener); - } - }, - - fireEvent: function (type, event) { - if (type == 'click') { - _.each(this._clickEvents, function (listener) { - listener(type, event); - }); - } - else { - this._divContainer.trigger(type, event); - } - }, - - _getElementPosition: function (elem) { - // Retrieve current element position. - var elementPosition = elem.getPosition(); - var x = elementPosition.x; - var y = elementPosition.y; - - // Add workspace offset. - x = x - this._padding.x; - y = y - this._padding.y; - - // Scale coordinate in order to be relative to the workspace. That's coord/size; - x = x / this._scale; - y = y / this._scale; - - // Remove decimal part.. - return {x: x, y: y}; - }, - - getWorkspaceIconPosition: function (e) { - // Retrieve current icon position. - var image = e.getImage(); - var elementPosition = image.getPosition(); - var imageSize = e.getSize(); - - //Add group offset - var iconGroup = e.getGroup(); - var group = iconGroup.getNativeElement(); - var coordOrigin = group.getCoordOrigin(); - var groupSize = group.getSize(); - var coordSize = group.getCoordSize(); - - var scale = {x: coordSize.width / parseInt(groupSize.width), y: coordSize.height / parseInt(groupSize.height)}; - - var x = (elementPosition.x - coordOrigin.x - (parseInt(imageSize.width) / 2)) / scale.x; - var y = (elementPosition.y - coordOrigin.y - (parseInt(imageSize.height) / 2)) / scale.y; - - //Retrieve iconGroup Position - var groupPosition = iconGroup.getPosition(); - x = x + groupPosition.x; - y = y + groupPosition.y; - - //Retrieve topic Position - var topic = iconGroup.getTopic(); - var topicPosition = this._getElementPosition(topic); - topicPosition.x = topicPosition.x - (parseInt(topic.getSize().width) / 2); - - // Remove decimal part.. - return {x: x + topicPosition.x, y: y + topicPosition.y}; - }, - - getWorkspaceMousePosition: function (event) { - // Retrieve current mouse position. - var x = event.clientX; - var y = event.clientY; - - //FIXME: paulo: why? Subtract div position. - /*var containerPosition = this.getContainer().position(); - x = x - containerPosition.x; - y = y - containerPosition.y;*/ - - // Scale coordinate in order to be relative to the workspace. That's coordSize/size; - x = x * this._scale; - y = y * this._scale; - - // Add workspace offset. - x = x + this._padding.x; - y = y + this._padding.y; - - // Remove decimal part.. - return new core.Point(x, y); - }, - - getContainer: function () { - return this._divContainer; - }, - - setOffset: function (x, y) { - this._padding.x = x; - this._padding.y = y; + removeEvent(event, listener) { + if (event == 'click') { + this._clickEvents.remove(listener); + } else { + this._divContainer.unbind(event, listener); } + }, + + fireEvent(type, event) { + if (type == 'click') { + _.each(this._clickEvents, (listener) => { + listener(type, event); + }); + } else { + this._divContainer.trigger(type, event); + } + }, + + _getElementPosition(elem) { + // Retrieve current element position. + const elementPosition = elem.getPosition(); + let { x } = elementPosition; + let { y } = elementPosition; + + // Add workspace offset. + x -= this._padding.x; + y -= this._padding.y; + + // Scale coordinate in order to be relative to the workspace. That's coord/size; + x /= this._scale; + y /= this._scale; + + // Remove decimal part.. + return { x, y }; + }, + + getWorkspaceIconPosition(e) { + // Retrieve current icon position. + const image = e.getImage(); + const elementPosition = image.getPosition(); + const imageSize = e.getSize(); + + // Add group offset + const iconGroup = e.getGroup(); + const group = iconGroup.getNativeElement(); + const coordOrigin = group.getCoordOrigin(); + const groupSize = group.getSize(); + const coordSize = group.getCoordSize(); + + const scale = { x: coordSize.width / parseInt(groupSize.width), y: coordSize.height / parseInt(groupSize.height) }; + + let x = (elementPosition.x - coordOrigin.x - (parseInt(imageSize.width) / 2)) / scale.x; + let y = (elementPosition.y - coordOrigin.y - (parseInt(imageSize.height) / 2)) / scale.y; + + // Retrieve iconGroup Position + const groupPosition = iconGroup.getPosition(); + x += groupPosition.x; + y += groupPosition.y; + + // Retrieve topic Position + const topic = iconGroup.getTopic(); + const topicPosition = this._getElementPosition(topic); + topicPosition.x -= (parseInt(topic.getSize().width) / 2); + + // Remove decimal part.. + return { x: x + topicPosition.x, y: y + topicPosition.y }; + }, + + getWorkspaceMousePosition(event) { + // Retrieve current mouse position. + let x = event.clientX; + let y = event.clientY; + + // FIXME: paulo: why? Subtract div position. + /* var containerPosition = this.getContainer().position(); + x = x - containerPosition.x; + y = y - containerPosition.y; */ + + // Scale coordinate in order to be relative to the workspace. That's coordSize/size; + x *= this._scale; + y *= this._scale; + + // Add workspace offset. + x += this._padding.x; + y += this._padding.y; + + // Remove decimal part.. + return new core.Point(x, y); + }, + + getContainer() { + return this._divContainer; + }, + + setOffset(x, y) { + this._padding.x = x; + this._padding.y = y; + }, }); export default ScreenManager; diff --git a/packages/mindplot/lib/components/ShrinkConnector.js b/packages/mindplot/lib/components/ShrinkConnector.js index 431027c3..ea02d655 100644 --- a/packages/mindplot/lib/components/ShrinkConnector.js +++ b/packages/mindplot/lib/components/ShrinkConnector.js @@ -15,100 +15,97 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const web2D = require('@wismapping/web2d') +const web2D = require('@wismapping/web2d'); + const web2d = web2D(); -const Topic = require('./Topic').default +const Topic = require('./Topic').default; const ActionDispatcher = require('./ActionDispatcher').default; const ShirinkConnector = new Class({ - initialize: function (topic) { + initialize(topic) { + const ellipse = new web2D.Elipse(Topic.prototype.INNER_RECT_ATTRIBUTES); + this._ellipse = ellipse; + ellipse.setFill('rgb(62,118,179)'); - var ellipse = new web2D.Elipse(Topic.prototype.INNER_RECT_ATTRIBUTES); - this._ellipse = ellipse; - ellipse.setFill('rgb(62,118,179)'); + ellipse.setSize(Topic.CONNECTOR_WIDTH, Topic.CONNECTOR_WIDTH); + ellipse.addEvent('click', (event) => { + const model = topic.getModel(); + const collapse = !model.areChildrenShrunken(); - ellipse.setSize(Topic.CONNECTOR_WIDTH, Topic.CONNECTOR_WIDTH); - ellipse.addEvent('click', function (event) { - var model = topic.getModel(); - var collapse = !model.areChildrenShrunken(); + const topicId = topic.getId(); + const actionDispatcher = ActionDispatcher.getInstance(); + actionDispatcher.shrinkBranch([topicId], collapse); - var topicId = topic.getId(); - var actionDispatcher = ActionDispatcher.getInstance(); - actionDispatcher.shrinkBranch([topicId], collapse); + event.stopPropagation(); + }); - event.stopPropagation(); + ellipse.addEvent('mousedown', (event) => { + // Avoid node creation ... + event.stopPropagation(); + }); - }); + ellipse.addEvent('dblclick', (event) => { + // Avoid node creation ... + event.stopPropagation(); + }); - ellipse.addEvent('mousedown', function (event) { - // Avoid node creation ... - event.stopPropagation(); - }); + ellipse.addEvent('mouseover', (event) => { + ellipse.setFill('rgb(153, 0, 255)'); + }); + const me = this; + ellipse.addEvent('mouseout', (event) => { + const color = topic.getBackgroundColor(); + me.setFill(color); + }); - ellipse.addEvent('dblclick', function (event) { - // Avoid node creation ... - event.stopPropagation(); - }); + ellipse.setCursor('default'); + this._fillColor = '#f7f7f7'; + const model = topic.getModel(); + this.changeRender(model.areChildrenShrunken()); + }, - ellipse.addEvent('mouseover', function (event) { - - ellipse.setFill('rgb(153, 0, 255)'); - }); - var me = this; - ellipse.addEvent('mouseout', function (event) { - var color = topic.getBackgroundColor(); - me.setFill(color); - }); - - ellipse.setCursor('default'); - this._fillColor = '#f7f7f7'; - var model = topic.getModel(); - this.changeRender(model.areChildrenShrunken()); - - }, - - changeRender: function (isShrink) { - var elipse = this._ellipse; - if (isShrink) { - elipse.setStroke('2', 'solid'); - } else { - elipse.setStroke('1', 'solid'); - } - }, - - setVisibility: function (value) { - this._ellipse.setVisibility(value); - }, - - setOpacity: function (opacity) { - this._ellipse.setOpacity(opacity); - }, - - setFill: function (color) { - this._fillColor = color; - this._ellipse.setFill(color); - }, - - setAttribute: function (name, value) { - this._ellipse.setAttribute(name, value); - }, - - addToWorkspace: function (group) { - group.append(this._ellipse); - }, - - setPosition: function (x, y) { - this._ellipse.setPosition(x, y); - }, - - moveToBack: function () { - this._ellipse.moveToBack(); - }, - - moveToFront: function () { - this._ellipse.moveToFront(); + changeRender(isShrink) { + const elipse = this._ellipse; + if (isShrink) { + elipse.setStroke('2', 'solid'); + } else { + elipse.setStroke('1', 'solid'); } + }, + + setVisibility(value) { + this._ellipse.setVisibility(value); + }, + + setOpacity(opacity) { + this._ellipse.setOpacity(opacity); + }, + + setFill(color) { + this._fillColor = color; + this._ellipse.setFill(color); + }, + + setAttribute(name, value) { + this._ellipse.setAttribute(name, value); + }, + + addToWorkspace(group) { + group.append(this._ellipse); + }, + + setPosition(x, y) { + this._ellipse.setPosition(x, y); + }, + + moveToBack() { + this._ellipse.moveToBack(); + }, + + moveToFront() { + this._ellipse.moveToFront(); + }, }); export default ShirinkConnector; diff --git a/packages/mindplot/lib/components/StandaloneActionDispatcher.js b/packages/mindplot/lib/components/StandaloneActionDispatcher.js index ebb7f74b..0442fa3d 100644 --- a/packages/mindplot/lib/components/StandaloneActionDispatcher.js +++ b/packages/mindplot/lib/components/StandaloneActionDispatcher.js @@ -29,353 +29,347 @@ const ChangeFeatureToTopicCommand = require('./commands/ChangeFeatureToTopicComm const NodeModel = require('./model/NodeModel').default; const StandaloneActionDispatcher = new Class( - /** @lends StandaloneActionDispatcher */ { - Extends: ActionDispatcher, - /** + /** @lends StandaloneActionDispatcher */ { + Extends: ActionDispatcher, + /** * @extends mindplot.ActionDispatcher * @constructs * @param {mindplot.CommandContext} commandContext */ - initialize: function (commandContext) { - this.parent(commandContext); - this._actionRunner = new DesignerActionRunner(commandContext, this); - }, + initialize(commandContext) { + this.parent(commandContext); + this._actionRunner = new DesignerActionRunner(commandContext, this); + }, - /** */ - addTopics: function (models, parentTopicsId) { - var command = new AddTopicCommand(models, parentTopicsId); - this.execute(command); - }, + /** */ + addTopics(models, parentTopicsId) { + const command = new AddTopicCommand(models, parentTopicsId); + this.execute(command); + }, - /** */ - addRelationship: function (model) { - var command = new AddRelationshipCommand(model); - this.execute(command); - }, + /** */ + addRelationship(model) { + const command = new AddRelationshipCommand(model); + this.execute(command); + }, - /** */ - deleteEntities: function (topicsIds, relIds) { - var command = new DeleteCommand(topicsIds, relIds); - this.execute(command); - }, + /** */ + deleteEntities(topicsIds, relIds) { + const command = new DeleteCommand(topicsIds, relIds); + this.execute(command); + }, - /** */ - dragTopic: function (topicId, position, order, parentTopic) { - var command = new DragTopicCommand(topicId, position, order, parentTopic); - this.execute(command); - }, + /** */ + dragTopic(topicId, position, order, parentTopic) { + const command = new DragTopicCommand(topicId, position, order, parentTopic); + this.execute(command); + }, - /** */ - moveTopic: function (topicId, position) { - $assert($defined(topicId), 'topicsId can not be null'); - $assert($defined(position), 'position can not be null'); + /** */ + moveTopic(topicId, position) { + $assert($defined(topicId), 'topicsId can not be null'); + $assert($defined(position), 'position can not be null'); - var commandFunc = function (topic, value) { - var result = topic.getPosition(); - EventBus.instance.fireEvent(EventBus.events.NodeMoveEvent, { - node: topic.getModel(), - position: value, - }); - return result; - }; + const commandFunc = function (topic, value) { + const result = topic.getPosition(); + EventBus.instance.fireEvent(EventBus.events.NodeMoveEvent, { + node: topic.getModel(), + position: value, + }); + return result; + }; - var command = new GenericFunctionCommand(commandFunc, topicId, position); - this.execute(command); - }, + const command = new GenericFunctionCommand(commandFunc, topicId, position); + this.execute(command); + }, - /** */ - moveControlPoint: function (ctrlPoint, point) { - var command = new MoveControlPointCommand(ctrlPoint, point); - this.execute(command); - }, + /** */ + moveControlPoint(ctrlPoint, point) { + const command = new MoveControlPointCommand(ctrlPoint, point); + this.execute(command); + }, - /** */ - changeFontStyleToTopic: function (topicsIds) { - var commandFunc = function (topic) { - var result = topic.getFontStyle(); - var style = result == 'italic' ? 'normal' : 'italic'; - topic.setFontStyle(style, true); - return result; - }; - var command = new GenericFunctionCommand(commandFunc, topicsIds); - this.execute(command); - }, + /** */ + changeFontStyleToTopic(topicsIds) { + const commandFunc = function (topic) { + const result = topic.getFontStyle(); + const style = result == 'italic' ? 'normal' : 'italic'; + topic.setFontStyle(style, true); + return result; + }; + const command = new GenericFunctionCommand(commandFunc, topicsIds); + this.execute(command); + }, - /** */ - changeTextToTopic: function (topicsIds, text) { - $assert($defined(topicsIds), 'topicsIds can not be null'); + /** */ + changeTextToTopic(topicsIds, text) { + $assert($defined(topicsIds), 'topicsIds can not be null'); - var commandFunc = function (topic, value) { - var result = topic.getText(); - topic.setText(value); - return result; - }; - commandFunc.commandType = 'changeTextToTopic'; + const commandFunc = function (topic, value) { + const result = topic.getText(); + topic.setText(value); + return result; + }; + commandFunc.commandType = 'changeTextToTopic'; - var command = new GenericFunctionCommand(commandFunc, topicsIds, text); - this.execute(command); - }, + const command = new GenericFunctionCommand(commandFunc, topicsIds, text); + this.execute(command); + }, - /** */ - changeFontFamilyToTopic: function (topicIds, fontFamily) { - $assert(topicIds, 'topicIds can not be null'); - $assert(fontFamily, 'fontFamily can not be null'); + /** */ + changeFontFamilyToTopic(topicIds, fontFamily) { + $assert(topicIds, 'topicIds can not be null'); + $assert(fontFamily, 'fontFamily can not be null'); - var commandFunc = function (topic, fontFamily) { - var result = topic.getFontFamily(); - topic.setFontFamily(fontFamily, true); + const commandFunc = function (topic, fontFamily) { + const result = topic.getFontFamily(); + topic.setFontFamily(fontFamily, true); - topic._adjustShapes(); - return result; - }; + topic._adjustShapes(); + return result; + }; - var command = new GenericFunctionCommand(commandFunc, topicIds, fontFamily); - this.execute(command); - }, + const command = new GenericFunctionCommand(commandFunc, topicIds, fontFamily); + this.execute(command); + }, - /** */ - changeFontColorToTopic: function (topicsIds, color) { - $assert(topicsIds, 'topicIds can not be null'); - $assert(color, 'color can not be null'); + /** */ + changeFontColorToTopic(topicsIds, color) { + $assert(topicsIds, 'topicIds can not be null'); + $assert(color, 'color can not be null'); - var commandFunc = function (topic, color) { - var result = topic.getFontColor(); - topic.setFontColor(color, true); - return result; - }; + const commandFunc = function (topic, color) { + const result = topic.getFontColor(); + topic.setFontColor(color, true); + return result; + }; - var command = new GenericFunctionCommand(commandFunc, topicsIds, color); - command.discardDuplicated = 'fontColorCommandId'; - this.execute(command); - }, + const command = new GenericFunctionCommand(commandFunc, topicsIds, color); + command.discardDuplicated = 'fontColorCommandId'; + this.execute(command); + }, - /** */ - changeBackgroundColorToTopic: function (topicsIds, color) { - $assert(topicsIds, 'topicIds can not be null'); - $assert(color, 'color can not be null'); + /** */ + changeBackgroundColorToTopic(topicsIds, color) { + $assert(topicsIds, 'topicIds can not be null'); + $assert(color, 'color can not be null'); - var commandFunc = function (topic, color) { - var result = topic.getBackgroundColor(); - topic.setBackgroundColor(color); - return result; - }; + const commandFunc = function (topic, color) { + const result = topic.getBackgroundColor(); + topic.setBackgroundColor(color); + return result; + }; - var command = new GenericFunctionCommand(commandFunc, topicsIds, color); - command.discardDuplicated = 'backColor'; - this.execute(command); - }, + const command = new GenericFunctionCommand(commandFunc, topicsIds, color); + command.discardDuplicated = 'backColor'; + this.execute(command); + }, - /** */ - changeBorderColorToTopic: function (topicsIds, color) { - $assert(topicsIds, 'topicIds can not be null'); - $assert(color, 'topicIds can not be null'); + /** */ + changeBorderColorToTopic(topicsIds, color) { + $assert(topicsIds, 'topicIds can not be null'); + $assert(color, 'topicIds can not be null'); - var commandFunc = function (topic, color) { - var result = topic.getBorderColor(); - topic.setBorderColor(color); - return result; - }; + const commandFunc = function (topic, color) { + const result = topic.getBorderColor(); + topic.setBorderColor(color); + return result; + }; - var command = new GenericFunctionCommand(commandFunc, topicsIds, color); - command.discardDuplicated = 'borderColorCommandId'; - this.execute(command); - }, + const command = new GenericFunctionCommand(commandFunc, topicsIds, color); + command.discardDuplicated = 'borderColorCommandId'; + this.execute(command); + }, - /** */ - changeFontSizeToTopic: function (topicsIds, size) { - $assert(topicsIds, 'topicIds can not be null'); - $assert(size, 'size can not be null'); + /** */ + changeFontSizeToTopic(topicsIds, size) { + $assert(topicsIds, 'topicIds can not be null'); + $assert(size, 'size can not be null'); - var commandFunc = function (topic, size) { - var result = topic.getFontSize(); - topic.setFontSize(size, true); + const commandFunc = function (topic, size) { + const result = topic.getFontSize(); + topic.setFontSize(size, true); - topic._adjustShapes(); - return result; - }; + topic._adjustShapes(); + return result; + }; - var command = new GenericFunctionCommand(commandFunc, topicsIds, size); - this.execute(command); - }, + const command = new GenericFunctionCommand(commandFunc, topicsIds, size); + this.execute(command); + }, - /** */ - changeShapeTypeToTopic: function (topicsIds, shapeType) { - $assert(topicsIds, 'topicsIds can not be null'); - $assert(shapeType, 'shapeType can not be null'); + /** */ + changeShapeTypeToTopic(topicsIds, shapeType) { + $assert(topicsIds, 'topicsIds can not be null'); + $assert(shapeType, 'shapeType can not be null'); - var commandFunc = function (topic, shapeType) { - var result = topic.getShapeType(); - topic.setShapeType(shapeType, true); - return result; - }; + const commandFunc = function (topic, shapeType) { + const result = topic.getShapeType(); + topic.setShapeType(shapeType, true); + return result; + }; - var command = new GenericFunctionCommand(commandFunc, topicsIds, shapeType); - this.execute(command); - }, + const command = new GenericFunctionCommand(commandFunc, topicsIds, shapeType); + this.execute(command); + }, - /** */ - changeFontWeightToTopic: function (topicsIds) { - $assert(topicsIds, 'topicsIds can not be null'); + /** */ + changeFontWeightToTopic(topicsIds) { + $assert(topicsIds, 'topicsIds can not be null'); - var commandFunc = function (topic) { - var result = topic.getFontWeight(); - var weight = result == 'bold' ? 'normal' : 'bold'; - topic.setFontWeight(weight, true); + const commandFunc = function (topic) { + const result = topic.getFontWeight(); + const weight = result == 'bold' ? 'normal' : 'bold'; + topic.setFontWeight(weight, true); - topic._adjustShapes(); - return result; - }; + topic._adjustShapes(); + return result; + }; - var command = new GenericFunctionCommand(commandFunc, topicsIds); - this.execute(command); - }, + const command = new GenericFunctionCommand(commandFunc, topicsIds); + this.execute(command); + }, - /** */ - shrinkBranch: function (topicsIds, collapse) { - $assert(topicsIds, 'topicsIds can not be null'); + /** */ + shrinkBranch(topicsIds, collapse) { + $assert(topicsIds, 'topicsIds can not be null'); - var commandFunc = function (topic, isShrink) { - topic.setChildrenShrunken(isShrink); - return !isShrink; - }; + const commandFunc = function (topic, isShrink) { + topic.setChildrenShrunken(isShrink); + return !isShrink; + }; - var command = new GenericFunctionCommand(commandFunc, topicsIds, collapse); - this.execute(command, false); - }, + const command = new GenericFunctionCommand(commandFunc, topicsIds, collapse); + this.execute(command, false); + }, - /** */ - addFeatureToTopic: function (topicId, featureType, attributes) { - var command = new AddFeatureToTopicCommand(topicId, featureType, attributes); - this.execute(command); - }, + /** */ + addFeatureToTopic(topicId, featureType, attributes) { + const command = new AddFeatureToTopicCommand(topicId, featureType, attributes); + this.execute(command); + }, - /** */ - changeFeatureToTopic: function (topicId, featureId, attributes) { - var command = new ChangeFeatureToTopicCommand(topicId, featureId, attributes); - this.execute(command); - }, + /** */ + changeFeatureToTopic(topicId, featureId, attributes) { + const command = new ChangeFeatureToTopicCommand(topicId, featureId, attributes); + this.execute(command); + }, - /** */ - removeFeatureFromTopic: function (topicId, featureId) { - var command = new RemoveFeatureFromTopicCommand(topicId, featureId); - this.execute(command); - }, + /** */ + removeFeatureFromTopic(topicId, featureId) { + const command = new RemoveFeatureFromTopicCommand(topicId, featureId); + this.execute(command); + }, - /** */ - execute: function (command) { - this._actionRunner.execute(command); - }, - } + /** */ + execute(command) { + this._actionRunner.execute(command); + }, + }, ); const CommandContext = new Class( - /** @lends CommandContext */ { - /** + /** @lends CommandContext */ { + /** * @constructs * @param {mindplot.Designer} designer */ - initialize: function (designer) { - $assert(designer, 'designer can not be null'); - this._designer = designer; - }, + initialize(designer) { + $assert(designer, 'designer can not be null'); + this._designer = designer; + }, - /** */ - findTopics: function (topicsIds) { - $assert($defined(topicsIds), 'topicsIds can not be null'); - if (!(topicsIds instanceof Array)) { - topicsIds = [topicsIds]; - } + /** */ + findTopics(topicsIds) { + $assert($defined(topicsIds), 'topicsIds can not be null'); + if (!(topicsIds instanceof Array)) { + topicsIds = [topicsIds]; + } - var designerTopics = this._designer.getModel().getTopics(); - var result = designerTopics.filter(function (topic) { - return topicsIds.contains(topic.getId()); - }); + const designerTopics = this._designer.getModel().getTopics(); + const result = designerTopics.filter((topic) => topicsIds.contains(topic.getId())); - if (result.length != topicsIds.length) { - var ids = designerTopics.map(function (topic) { - return topic.getId(); - }); - $assert( - result.length == topicsIds.length, - 'Could not find topic. Result:' + - result + - ', Filter Criteria:' + - topicsIds + - ', Current Topics: [' + - ids + - ']' - ); - } - return result; - }, + if (result.length != topicsIds.length) { + const ids = designerTopics.map((topic) => topic.getId()); + $assert( + result.length == topicsIds.length, + `Could not find topic. Result:${ + result + }, Filter Criteria:${ + topicsIds + }, Current Topics: [${ + ids + }]`, + ); + } + return result; + }, - /** */ - deleteTopic: function (topic) { - this._designer.removeTopic(topic); - }, + /** */ + deleteTopic(topic) { + this._designer.removeTopic(topic); + }, - /** */ - createTopic: function (model) { - $assert(model, 'model can not be null'); - return this._designer.nodeModelToNodeGraph(model); - }, + /** */ + createTopic(model) { + $assert(model, 'model can not be null'); + return this._designer.nodeModelToNodeGraph(model); + }, - /** */ - createModel: function () { - var mindmap = this._designer.getMindmap(); - return mindmap.createNode(NodeModel.MAIN_TOPIC_TYPE); - }, + /** */ + createModel() { + const mindmap = this._designer.getMindmap(); + return mindmap.createNode(NodeModel.MAIN_TOPIC_TYPE); + }, - /** */ - addTopic: function (topic) { - var mindmap = this._designer.getMindmap(); - return mindmap.addBranch(topic.getModel()); - }, + /** */ + addTopic(topic) { + const mindmap = this._designer.getMindmap(); + return mindmap.addBranch(topic.getModel()); + }, - /** */ - connect: function (childTopic, parentTopic) { - childTopic.connectTo(parentTopic, this._designer._workspace); - }, + /** */ + connect(childTopic, parentTopic) { + childTopic.connectTo(parentTopic, this._designer._workspace); + }, - /** */ - disconnect: function (topic) { - topic.disconnect(this._designer._workspace); - }, + /** */ + disconnect(topic) { + topic.disconnect(this._designer._workspace); + }, - /** */ - addRelationship: function (model) { - $assert(model, 'model cannot be null'); - return this._designer.addRelationship(model); - }, + /** */ + addRelationship(model) { + $assert(model, 'model cannot be null'); + return this._designer.addRelationship(model); + }, - /** */ - deleteRelationship: function (relationship) { - this._designer.deleteRelationship(relationship); - }, + /** */ + deleteRelationship(relationship) { + this._designer.deleteRelationship(relationship); + }, - /** */ - findRelationships: function (relIds) { - $assert($defined(relIds), 'relId can not be null'); - if (!(relIds instanceof Array)) { - relIds = [relIds]; - } + /** */ + findRelationships(relIds) { + $assert($defined(relIds), 'relId can not be null'); + if (!(relIds instanceof Array)) { + relIds = [relIds]; + } - var designerRel = this._designer.getModel().getRelationships(); - return designerRel.filter(function (rel) { - return relIds.contains(rel.getId()); - }); - }, + const designerRel = this._designer.getModel().getRelationships(); + return designerRel.filter((rel) => relIds.contains(rel.getId())); + }, - /** */ - moveTopic: function (topic, position) { - $assert(topic, 'topic cannot be null'); - $assert(position, 'position cannot be null'); - EventBus.instance.fireEvent(EventBus.events.NodeMoveEvent, { - node: topic.getModel(), - position: position, - }); - }, - } + /** */ + moveTopic(topic, position) { + $assert(topic, 'topic cannot be null'); + $assert(position, 'position cannot be null'); + EventBus.instance.fireEvent(EventBus.events.NodeMoveEvent, { + node: topic.getModel(), + position, + }); + }, + }, ); export { StandaloneActionDispatcher, CommandContext }; diff --git a/packages/mindplot/lib/components/TextEditor.js b/packages/mindplot/lib/components/TextEditor.js index 4e22825b..29864daf 100644 --- a/packages/mindplot/lib/components/TextEditor.js +++ b/packages/mindplot/lib/components/TextEditor.js @@ -1,270 +1,260 @@ -/* - * Copyright [2015] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -const web2D = require('@wismapping/web2d') -const web2d = web2D() - -const ActionDispatcher = require('./ActionDispatcher').default - -//FIXME: Not used! -const TextEditor = new Class({ - initialize: function (topic) { - this._topic = topic; - }, - - _buildEditor: function () { - - this._size = {width: 500, height: 100}; - var result = new Element('div'); - result.setStyles({ - position: "absolute", - display: "none", - zIndex: "8", - width: "500px", - height: "100px" - } - ); - - - var inputContainer = new Element('div'); - inputContainer.setStyles({ - border: "none", - overflow: "auto" - }); - inputContainer.inject(result); - - var inputText = new Element('input', - { - type: "text", - tabindex: '-1', - value: "" - } - ); - inputText.setStyles({ - border: "none", - background: "transparent" - }); - inputText.inject(inputContainer); - - var spanContainer = new Element('div'); - spanContainer.setStyle('visibility', "hidden"); - spanContainer.inject(result); - - var spanElem = new Element('span', {tabindex: "-1"}); - spanElem.setStyle('white-space', "nowrap"); - spanElem.setStyle('nowrap', 'nowrap'); - spanElem.inject(spanContainer); - - - return result; - }, - - _registerEvents: function (divElem) { - var inputElem = this._getTextareaElem(); - var spanElem = this._getSpanElem(); - var me = this; - - divElem.addEvent('keydown', function (event) { - switch (event.key) { - case 'esc': - me.close(false); - break; - case 'enter': - me.close(true); - break; - default: - spanElem.innerHTML = inputElem.value; - var size = inputElem.value.length + 1; - inputElem.size = size; - if (spanElem.offsetWidth > (parseInt(divElem.style.width) - 100)) { - divElem.style.width = (spanElem.offsetWidth + 100) + "px"; - } - break; - } - event.stopPropagation(); - }); - - // If the user clicks on the input, all event must be ignored ... - divElem.addEvent('click', function (event) { - event.stopPropagation(); - }); - divElem.addEvent('dblclick', function (event) { - event.stopPropagation(); - }); - divElem.addEvent('mousedown', function (event) { - event.stopPropagation(); - }); - }, - - isVisible: function () { - return $defined(this._containerElem) && this._containerElem.getStyle('display') == 'block'; - }, - - _updateModel: function () { - - if (this._topic.getText() != this._getText()) { - var text = this._getText(); - var topicId = this._topic.getId(); - - var actionDispatcher = ActionDispatcher.getInstance(); - actionDispatcher.changeTextToTopic([topicId], text); - } - }, - - show: function (text) { - - if (!this.isVisible()) { - //Create editor ui - var editorElem = this._buildEditor(); - editorElem.inject($(document.body)[0]); - - this._containerElem = editorElem; - this._registerEvents(editorElem); - this._showEditor(text); - } - }, - - _showEditor: function (defaultText) { - - var topic = this._topic; - - // Hide topic text ... - topic.getTextShape().setVisibility(false); - - // Set Editor Style - var nodeText = topic.getTextShape(); - var font = nodeText.getFont(); - font.size = nodeText.getHtmlFontSize(); - font.color = nodeText.getColor(); - this._setStyle(font); - - // Set editor's initial text - var text = $defined(defaultText) ? defaultText : topic.getText(); - this._setText(text); - - var me = this; - // Set editor's initial size - var displayFunc = function () { - // Position the editor and set the size... - var textShape = me._topic.getTextShape(); - - me._containerElem.css('display', 'block'); - - me._containerElem.offset(textShape.getNativePosition()); - // Set size ... - var elemSize = topic.getSize(); - me._setEditorSize(elemSize.width, elemSize.height); - - var textareaElem = me._getTextareaElem(); - textareaElem.focus(); - me._positionCursor(textareaElem, !$defined(defaultText)); - - }; - - displayFunc.delay(10); - }, - - _setStyle: function (fontStyle) { - var inputField = this._getTextareaElem(); - var spanField = this._getSpanElem(); - if (!$defined(fontStyle.font)) { - fontStyle.font = "Arial"; - } - if (!$defined(fontStyle.style)) { - fontStyle.style = "normal"; - } - if (!$defined(fontStyle.weight)) { - fontStyle.weight = "normal"; - } - if (!$defined(fontStyle.size)) { - fontStyle.size = 12; - } - inputField.style.fontSize = fontStyle.size + "px"; - inputField.style.fontFamily = fontStyle.font; - inputField.style.fontStyle = fontStyle.style; - inputField.style.fontWeight = fontStyle.weight; - inputField.style.color = fontStyle.color; - spanField.style.fontFamily = fontStyle.font; - spanField.style.fontStyle = fontStyle.style; - spanField.style.fontWeight = fontStyle.weight; - spanField.style.fontSize = fontStyle.size + "px"; - }, - - _setText: function (text) { - var inputField = this._getTextareaElem(); - inputField.size = text.length + 1; - this._containerElem.style.width = (inputField.size * parseInt(inputField.style.fontSize) + 100) + "px"; - var spanField = this._getSpanElem(); - spanField.innerHTML = text; - inputField.value = text; - }, - - _getText: function () { - return this._getTextareaElem().value; - }, - - _getTextareaElem: function () { - return this._containerElem.getElement('input'); - }, - - _getSpanElem: function () { - return this._containerElem.getElement('span'); - }, - - _setEditorSize: function (width, height) { - var textShape = this._topic.getTextShape(); - var scale = web2d.utils.TransformUtil.workoutScale(textShape._peer); - this._size = {width: width * scale.width, height: height * scale.height}; - this._containerElem.style.width = this._size.width * 2 + "px"; - this._containerElem.style.height = this._size.height + "px"; - }, - - _positionCursor: function (inputElem, selectText) { - // Select text if it's required ... - if (inputElem.createTextRange) //ie - { - var range = inputElem.createTextRange(); - var pos = inputElem.value.length; - if (!selectText) { - range.select(); - range.move("character", pos); - } - else { - range.move("character", pos); - range.select(); - } - } - else if (!selectText) { - inputElem.setSelectionRange(0, inputElem.value.length); - } - }, - - close: function (update) { - if (this.isVisible()) { - // Update changes ... - if (!$defined(update) || update) { - this._updateModel(); - } - - // Let make the visible text in the node visible again ... - this._topic.getTextShape().setVisibility(true); - - // Remove it form the screen ... - this._containerElem.dispose(); - this._containerElem = null; - } - } -}); - -export default TextEditor; +/* + * Copyright [2015] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const web2D = require('@wismapping/web2d'); + +const web2d = web2D(); + +const ActionDispatcher = require('./ActionDispatcher').default; + +// FIXME: Not used! +const TextEditor = new Class({ + initialize(topic) { + this._topic = topic; + }, + + _buildEditor() { + this._size = { width: 500, height: 100 }; + const result = new Element('div'); + result.setStyles({ + position: 'absolute', + display: 'none', + zIndex: '8', + width: '500px', + height: '100px', + }); + + const inputContainer = new Element('div'); + inputContainer.setStyles({ + border: 'none', + overflow: 'auto', + }); + inputContainer.inject(result); + + const inputText = new Element('input', + { + type: 'text', + tabindex: '-1', + value: '', + }); + inputText.setStyles({ + border: 'none', + background: 'transparent', + }); + inputText.inject(inputContainer); + + const spanContainer = new Element('div'); + spanContainer.setStyle('visibility', 'hidden'); + spanContainer.inject(result); + + const spanElem = new Element('span', { tabindex: '-1' }); + spanElem.setStyle('white-space', 'nowrap'); + spanElem.setStyle('nowrap', 'nowrap'); + spanElem.inject(spanContainer); + + return result; + }, + + _registerEvents(divElem) { + const inputElem = this._getTextareaElem(); + const spanElem = this._getSpanElem(); + const me = this; + + divElem.addEvent('keydown', (event) => { + switch (event.key) { + case 'esc': + me.close(false); + break; + case 'enter': + me.close(true); + break; + default: + spanElem.innerHTML = inputElem.value; + var size = inputElem.value.length + 1; + inputElem.size = size; + if (spanElem.offsetWidth > (parseInt(divElem.style.width) - 100)) { + divElem.style.width = `${spanElem.offsetWidth + 100}px`; + } + break; + } + event.stopPropagation(); + }); + + // If the user clicks on the input, all event must be ignored ... + divElem.addEvent('click', (event) => { + event.stopPropagation(); + }); + divElem.addEvent('dblclick', (event) => { + event.stopPropagation(); + }); + divElem.addEvent('mousedown', (event) => { + event.stopPropagation(); + }); + }, + + isVisible() { + return $defined(this._containerElem) && this._containerElem.getStyle('display') == 'block'; + }, + + _updateModel() { + if (this._topic.getText() != this._getText()) { + const text = this._getText(); + const topicId = this._topic.getId(); + + const actionDispatcher = ActionDispatcher.getInstance(); + actionDispatcher.changeTextToTopic([topicId], text); + } + }, + + show(text) { + if (!this.isVisible()) { + // Create editor ui + const editorElem = this._buildEditor(); + editorElem.inject($(document.body)[0]); + + this._containerElem = editorElem; + this._registerEvents(editorElem); + this._showEditor(text); + } + }, + + _showEditor(defaultText) { + const topic = this._topic; + + // Hide topic text ... + topic.getTextShape().setVisibility(false); + + // Set Editor Style + const nodeText = topic.getTextShape(); + const font = nodeText.getFont(); + font.size = nodeText.getHtmlFontSize(); + font.color = nodeText.getColor(); + this._setStyle(font); + + // Set editor's initial text + const text = $defined(defaultText) ? defaultText : topic.getText(); + this._setText(text); + + const me = this; + // Set editor's initial size + const displayFunc = function () { + // Position the editor and set the size... + const textShape = me._topic.getTextShape(); + + me._containerElem.css('display', 'block'); + + me._containerElem.offset(textShape.getNativePosition()); + // Set size ... + const elemSize = topic.getSize(); + me._setEditorSize(elemSize.width, elemSize.height); + + const textareaElem = me._getTextareaElem(); + textareaElem.focus(); + me._positionCursor(textareaElem, !$defined(defaultText)); + }; + + displayFunc.delay(10); + }, + + _setStyle(fontStyle) { + const inputField = this._getTextareaElem(); + const spanField = this._getSpanElem(); + if (!$defined(fontStyle.font)) { + fontStyle.font = 'Arial'; + } + if (!$defined(fontStyle.style)) { + fontStyle.style = 'normal'; + } + if (!$defined(fontStyle.weight)) { + fontStyle.weight = 'normal'; + } + if (!$defined(fontStyle.size)) { + fontStyle.size = 12; + } + inputField.style.fontSize = `${fontStyle.size}px`; + inputField.style.fontFamily = fontStyle.font; + inputField.style.fontStyle = fontStyle.style; + inputField.style.fontWeight = fontStyle.weight; + inputField.style.color = fontStyle.color; + spanField.style.fontFamily = fontStyle.font; + spanField.style.fontStyle = fontStyle.style; + spanField.style.fontWeight = fontStyle.weight; + spanField.style.fontSize = `${fontStyle.size}px`; + }, + + _setText(text) { + const inputField = this._getTextareaElem(); + inputField.size = text.length + 1; + this._containerElem.style.width = `${inputField.size * parseInt(inputField.style.fontSize) + 100}px`; + const spanField = this._getSpanElem(); + spanField.innerHTML = text; + inputField.value = text; + }, + + _getText() { + return this._getTextareaElem().value; + }, + + _getTextareaElem() { + return this._containerElem.getElement('input'); + }, + + _getSpanElem() { + return this._containerElem.getElement('span'); + }, + + _setEditorSize(width, height) { + const textShape = this._topic.getTextShape(); + const scale = web2d.utils.TransformUtil.workoutScale(textShape._peer); + this._size = { width: width * scale.width, height: height * scale.height }; + this._containerElem.style.width = `${this._size.width * 2}px`; + this._containerElem.style.height = `${this._size.height}px`; + }, + + _positionCursor(inputElem, selectText) { + // Select text if it's required ... + if (inputElem.createTextRange) // ie + { + const range = inputElem.createTextRange(); + const pos = inputElem.value.length; + if (!selectText) { + range.select(); + range.move('character', pos); + } else { + range.move('character', pos); + range.select(); + } + } else if (!selectText) { + inputElem.setSelectionRange(0, inputElem.value.length); + } + }, + + close(update) { + if (this.isVisible()) { + // Update changes ... + if (!$defined(update) || update) { + this._updateModel(); + } + + // Let make the visible text in the node visible again ... + this._topic.getTextShape().setVisibility(true); + + // Remove it form the screen ... + this._containerElem.dispose(); + this._containerElem = null; + } + }, +}); + +export default TextEditor; diff --git a/packages/mindplot/lib/components/TextEditorFactory.js b/packages/mindplot/lib/components/TextEditorFactory.js index a1991df0..a2016404 100644 --- a/packages/mindplot/lib/components/TextEditorFactory.js +++ b/packages/mindplot/lib/components/TextEditorFactory.js @@ -20,11 +20,11 @@ const TextEditor = require('./TextEditor').default; const TextEditorFactory = {}; TextEditorFactory.getTextEditorFromName = function (name) { - var editorClass = null; - if (name == 'RichTextEditor') { - editorClass = RichTextEditor; - } else { - editorClass = TextEditor; - } - return editorClass; + let editorClass = null; + if (name == 'RichTextEditor') { + editorClass = RichTextEditor; + } else { + editorClass = TextEditor; + } + return editorClass; }; diff --git a/packages/mindplot/lib/components/Topic.js b/packages/mindplot/lib/components/Topic.js index d492aac9..5bd9922e 100644 --- a/packages/mindplot/lib/components/Topic.js +++ b/packages/mindplot/lib/components/Topic.js @@ -16,6 +16,7 @@ * limitations under the License. */ const web2D = require('@wismapping/web2d'); + const web2d = web2D(); const NodeGraph = require('./NodeGraph').default; const { TopicShape } = require('./model/INodeModel'); @@ -33,1307 +34,1304 @@ const TopicEventDispatcher = require('./TopicEventDispatcher').default; const INodeModel = require('./model/INodeModel').default; const Topic = new Class( - /** @lends Topic */ { - Extends: NodeGraph, - /** + /** @lends Topic */ { + Extends: NodeGraph, + /** * @extends mindplot.NodeGraph * @constructs * @param model * @param options */ - initialize: function (model, options) { - this.parent(model, options); - this._children = []; - this._parent = null; - this._relationships = []; - this._isInWorkspace = false; - this._buildTopicShape(); + initialize(model, options) { + this.parent(model, options); + this._children = []; + this._parent = null; + this._relationships = []; + this._isInWorkspace = false; + this._buildTopicShape(); - // Position a topic .... - var pos = model.getPosition(); - if (pos != null && this.isCentralTopic()) { - this.setPosition(pos); - } + // Position a topic .... + const pos = model.getPosition(); + if (pos != null && this.isCentralTopic()) { + this.setPosition(pos); + } - // Register events for the topic ... - if (!this.isReadOnly()) { - this._registerEvents(); - } - }, + // Register events for the topic ... + if (!this.isReadOnly()) { + this._registerEvents(); + } + }, - _registerEvents: function () { - this.setMouseEventsEnabled(true); + _registerEvents() { + this.setMouseEventsEnabled(true); - // Prevent click on the topics being propagated ... - this.addEvent('click', function (event) { - event.stopPropagation(); - }); - var me = this; - this.addEvent('dblclick', function (event) { - me._getTopicEventDispatcher().show(me); - event.stopPropagation(); - }); - }, + // Prevent click on the topics being propagated ... + this.addEvent('click', (event) => { + event.stopPropagation(); + }); + const me = this; + this.addEvent('dblclick', (event) => { + me._getTopicEventDispatcher().show(me); + event.stopPropagation(); + }); + }, - /** + /** * @param {String} type the topic shape type * @see {@link mindplot.model.INodeModel} */ - setShapeType: function (type) { - this._setShapeType(type, true); - }, + setShapeType(type) { + this._setShapeType(type, true); + }, - /** @return {mindplot.Topic} parent topic */ - getParent: function () { - return this._parent; - }, + /** @return {mindplot.Topic} parent topic */ + getParent() { + return this._parent; + }, - _setShapeType: function (type, updateModel) { - // Remove inner shape figure ... - var model = this.getModel(); - if ($defined(updateModel) && updateModel) { - model.setShapeType(type); - } + _setShapeType(type, updateModel) { + // Remove inner shape figure ... + const model = this.getModel(); + if ($defined(updateModel) && updateModel) { + model.setShapeType(type); + } - var oldInnerShape = this.getInnerShape(); - if (oldInnerShape != null) { - this._removeInnerShape(); + const oldInnerShape = this.getInnerShape(); + if (oldInnerShape != null) { + this._removeInnerShape(); - // Create a new one ... - var innerShape = this.getInnerShape(); + // Create a new one ... + const innerShape = this.getInnerShape(); - // Update figure size ... - var size = this.getSize(); - this.setSize(size, true); + // Update figure size ... + const size = this.getSize(); + this.setSize(size, true); - var group = this.get2DElement(); - group.append(innerShape); + const group = this.get2DElement(); + group.append(innerShape); - // Move text to the front ... - var text = this.getTextShape(); - text.moveToFront(); + // Move text to the front ... + const text = this.getTextShape(); + text.moveToFront(); - //Move iconGroup to front ... - var iconGroup = this.getIconGroup(); - if ($defined(iconGroup)) { - iconGroup.moveToFront(); - } + // Move iconGroup to front ... + const iconGroup = this.getIconGroup(); + if ($defined(iconGroup)) { + iconGroup.moveToFront(); + } - //Move connector to front - var connector = this.getShrinkConnector(); - if ($defined(connector)) { - connector.moveToFront(); - } - } - }, + // Move connector to front + const connector = this.getShrinkConnector(); + if ($defined(connector)) { + connector.moveToFront(); + } + } + }, - /** @return {String} topic shape type */ - getShapeType: function () { - var model = this.getModel(); - var result = model.getShapeType(); - if (!$defined(result)) { - result = TopicStyle.defaultShapeType(this); - } - return result; - }, + /** @return {String} topic shape type */ + getShapeType() { + const model = this.getModel(); + let result = model.getShapeType(); + if (!$defined(result)) { + result = TopicStyle.defaultShapeType(this); + } + return result; + }, - _removeInnerShape: function () { - var group = this.get2DElement(); - var innerShape = this.getInnerShape(); - group.removeChild(innerShape); - this._innerShape = null; - return innerShape; - }, + _removeInnerShape() { + const group = this.get2DElement(); + const innerShape = this.getInnerShape(); + group.removeChild(innerShape); + this._innerShape = null; + return innerShape; + }, - /** @return {web2d.Line|web2d.Rect|web2d.Image} inner shape of the topic */ - getInnerShape: function () { - if (!$defined(this._innerShape)) { - // Create inner box. - this._innerShape = this._buildShape( - Topic.INNER_RECT_ATTRIBUTES, - this.getShapeType() - ); + /** @return {web2d.Line|web2d.Rect|web2d.Image} inner shape of the topic */ + getInnerShape() { + if (!$defined(this._innerShape)) { + // Create inner box. + this._innerShape = this._buildShape( + Topic.INNER_RECT_ATTRIBUTES, + this.getShapeType(), + ); - // Update bgcolor ... - var bgColor = this.getBackgroundColor(); - this._setBackgroundColor(bgColor, false); + // Update bgcolor ... + const bgColor = this.getBackgroundColor(); + this._setBackgroundColor(bgColor, false); - // Update border color ... - var brColor = this.getBorderColor(); - this._setBorderColor(brColor, false); + // Update border color ... + const brColor = this.getBorderColor(); + this._setBorderColor(brColor, false); - // Define the pointer ... - if (!this.isCentralTopic() && !this.isReadOnly()) { - this._innerShape.setCursor('move'); - } else { - this._innerShape.setCursor('default'); - } - } - return this._innerShape; - }, + // Define the pointer ... + if (!this.isCentralTopic() && !this.isReadOnly()) { + this._innerShape.setCursor('move'); + } else { + this._innerShape.setCursor('default'); + } + } + return this._innerShape; + }, - _buildShape: function (attributes, shapeType) { - $assert(attributes, 'attributes can not be null'); - $assert(shapeType, 'shapeType can not be null'); + _buildShape(attributes, shapeType) { + $assert(attributes, 'attributes can not be null'); + $assert(shapeType, 'shapeType can not be null'); - var result; - if (shapeType == TopicShape.RECTANGLE) { - result = new web2d.Rect(0, attributes); - } else if (shapeType == TopicShape.IMAGE) { - var model = this.getModel(); - var url = model.getImageUrl(); - var size = model.getImageSize(); + let result; + if (shapeType == TopicShape.RECTANGLE) { + result = new web2d.Rect(0, attributes); + } else if (shapeType == TopicShape.IMAGE) { + const model = this.getModel(); + const url = model.getImageUrl(); + const size = model.getImageSize(); - result = new web2d.Image(); - result.setHref(url); - result.setSize(size.width, size.height); + result = new web2d.Image(); + result.setHref(url); + result.setSize(size.width, size.height); - result.getSize = function () { - return model.getImageSize(); - }; + result.getSize = function () { + return model.getImageSize(); + }; - result.setPosition = function () {}; - } else if (shapeType == TopicShape.ELLIPSE) { - result = new web2d.Rect(0.9, attributes); - } else if (shapeType == TopicShape.ROUNDED_RECT) { - result = new web2d.Rect(0.3, attributes); - } else if (shapeType == TopicShape.LINE) { - result = new web2d.Line({ strokeColor: '#495879', strokeWidth: 1 }); - result.setSize = function (width, height) { - this.size = { width: width, height: height }; - result.setFrom(0, height); - result.setTo(width, height); + result.setPosition = function () {}; + } else if (shapeType == TopicShape.ELLIPSE) { + result = new web2d.Rect(0.9, attributes); + } else if (shapeType == TopicShape.ROUNDED_RECT) { + result = new web2d.Rect(0.3, attributes); + } else if (shapeType == TopicShape.LINE) { + result = new web2d.Line({ strokeColor: '#495879', strokeWidth: 1 }); + result.setSize = function (width, height) { + this.size = { width, height }; + result.setFrom(0, height); + result.setTo(width, height); - // Lines will have the same color of the default connection lines... - var stokeColor = ConnectionLine.getStrokeColor(); - result.setStroke(1, 'solid', stokeColor); - }; + // Lines will have the same color of the default connection lines... + const stokeColor = ConnectionLine.getStrokeColor(); + result.setStroke(1, 'solid', stokeColor); + }; - result.getSize = function () { - return this.size; - }; + result.getSize = function () { + return this.size; + }; - result.setPosition = function () {}; + result.setPosition = function () {}; - result.setFill = function () {}; + result.setFill = function () {}; - result.setStroke = function () {}; - } else { - $assert(false, 'Unsupported figure shapeType:' + shapeType); - } - result.setPosition(0, 0); - return result; - }, + result.setStroke = function () {}; + } else { + $assert(false, `Unsupported figure shapeType:${shapeType}`); + } + result.setPosition(0, 0); + return result; + }, - /** @param {String} type the cursor type, either 'pointer', 'default' or 'move' */ - setCursor: function (type) { - var innerShape = this.getInnerShape(); - innerShape.setCursor(type); + /** @param {String} type the cursor type, either 'pointer', 'default' or 'move' */ + setCursor(type) { + const innerShape = this.getInnerShape(); + innerShape.setCursor(type); - var outerShape = this.getOuterShape(); - outerShape.setCursor(type); + const outerShape = this.getOuterShape(); + outerShape.setCursor(type); - var textShape = this.getTextShape(); - textShape.setCursor(type); - }, + const textShape = this.getTextShape(); + textShape.setCursor(type); + }, - /** @return outer shape */ - getOuterShape: function () { - if (!$defined(this._outerShape)) { - var rect = this._buildShape(Topic.OUTER_SHAPE_ATTRIBUTES, TopicShape.ROUNDED_RECT); - rect.setPosition(-2, -3); - rect.setOpacity(0); - this._outerShape = rect; - } + /** @return outer shape */ + getOuterShape() { + if (!$defined(this._outerShape)) { + const rect = this._buildShape(Topic.OUTER_SHAPE_ATTRIBUTES, TopicShape.ROUNDED_RECT); + rect.setPosition(-2, -3); + rect.setOpacity(0); + this._outerShape = rect; + } - return this._outerShape; - }, + return this._outerShape; + }, - /** @return text shape */ - getTextShape: function () { - if (!$defined(this._text)) { - this._text = this._buildTextShape(false); + /** @return text shape */ + getTextShape() { + if (!$defined(this._text)) { + this._text = this._buildTextShape(false); - // Set Text ... - var text = this.getText(); - this._setText(text, false); - } + // Set Text ... + const text = this.getText(); + this._setText(text, false); + } - return this._text; - }, + return this._text; + }, - /** @return icon group */ - getOrBuildIconGroup: function () { - if (!$defined(this._iconsGroup)) { - this._iconsGroup = this._buildIconGroup(); - var group = this.get2DElement(); - group.append(this._iconsGroup.getNativeElement()); - this._iconsGroup.moveToFront(); - } - return this._iconsGroup; - }, + /** @return icon group */ + getOrBuildIconGroup() { + if (!$defined(this._iconsGroup)) { + this._iconsGroup = this._buildIconGroup(); + const group = this.get2DElement(); + group.append(this._iconsGroup.getNativeElement()); + this._iconsGroup.moveToFront(); + } + return this._iconsGroup; + }, - /** */ - getIconGroup: function () { - return this._iconsGroup; - }, + /** */ + getIconGroup() { + return this._iconsGroup; + }, - _buildIconGroup: function () { - var textHeight = this.getTextShape().getFontHeight(); - var result = new IconGroup(this.getId(), textHeight); - var padding = TopicStyle.getInnerPadding(this); - result.setPosition(padding, padding); + _buildIconGroup() { + const textHeight = this.getTextShape().getFontHeight(); + const result = new IconGroup(this.getId(), textHeight); + const padding = TopicStyle.getInnerPadding(this); + result.setPosition(padding, padding); - // Load topic features ... - var model = this.getModel(); - var featuresModel = model.getFeatures(); - for (var i = 0; i < featuresModel.length; i++) { - var featureModel = featuresModel[i]; - var icon = TopicFeature.createIcon(this, featureModel, this.isReadOnly()); - result.addIcon( - icon, - featureModel.getType() == TopicFeature.Icon.id && !this.isReadOnly() - ); - } + // Load topic features ... + const model = this.getModel(); + const featuresModel = model.getFeatures(); + for (let i = 0; i < featuresModel.length; i++) { + const featureModel = featuresModel[i]; + const icon = TopicFeature.createIcon(this, featureModel, this.isReadOnly()); + result.addIcon( + icon, + featureModel.getType() == TopicFeature.Icon.id && !this.isReadOnly(), + ); + } - return result; - }, + return result; + }, - /** + /** * assigns the new feature model to the topic's node model and adds the respective icon * @param {mindplot.model.FeatureModel} featureModel * @return {mindplot.Icon} the icon corresponding to the feature model */ - addFeature: function (featureModel) { - var iconGroup = this.getOrBuildIconGroup(); - this.closeEditors(); + addFeature(featureModel) { + const iconGroup = this.getOrBuildIconGroup(); + this.closeEditors(); - // Update model ... - var model = this.getModel(); - model.addFeature(featureModel); + // Update model ... + const model = this.getModel(); + model.addFeature(featureModel); - var result = TopicFeature.createIcon(this, featureModel, this.isReadOnly()); - iconGroup.addIcon( - result, - featureModel.getType() == TopicFeature.Icon.id && !this.isReadOnly() - ); + const result = TopicFeature.createIcon(this, featureModel, this.isReadOnly()); + iconGroup.addIcon( + result, + featureModel.getType() == TopicFeature.Icon.id && !this.isReadOnly(), + ); - this._adjustShapes(); - return result; + this._adjustShapes(); + return result; + }, + + /** */ + findFeatureById(id) { + const model = this.getModel(); + return model.findFeatureById(id); + }, + + /** */ + removeFeature(featureModel) { + $assert(featureModel, 'featureModel could not be null'); + + // Removing the icon from MODEL + const model = this.getModel(); + model.removeFeature(featureModel); + + // Removing the icon from UI + const iconGroup = this.getIconGroup(); + if ($defined(iconGroup)) { + iconGroup.removeIconByModel(featureModel); + } + this._adjustShapes(); + }, + + /** */ + addRelationship(relationship) { + this._relationships.push(relationship); + }, + + /** */ + deleteRelationship(relationship) { + this._relationships.erase(relationship); + }, + + /** */ + getRelationships() { + return this._relationships; + }, + + _buildTextShape(readOnly) { + const result = new web2d.Text(); + const family = this.getFontFamily(); + const size = this.getFontSize(); + const weight = this.getFontWeight(); + const style = this.getFontStyle(); + result.setFont(family, size, style, weight); + + const color = this.getFontColor(); + result.setColor(color); + + if (!readOnly) { + // Propagate mouse events ... + if (!this.isCentralTopic()) { + result.setCursor('move'); + } else { + result.setCursor('default'); + } + } + + return result; + }, + + /** */ + setFontFamily(value, updateModel) { + const textShape = this.getTextShape(); + textShape.setFontFamily(value); + if ($defined(updateModel) && updateModel) { + const model = this.getModel(); + model.setFontFamily(value); + } + this._adjustShapes(updateModel); + }, + + /** */ + setFontSize(value, updateModel) { + const textShape = this.getTextShape(); + textShape.setSize(value); + + if ($defined(updateModel) && updateModel) { + const model = this.getModel(); + model.setFontSize(value); + } + this._adjustShapes(updateModel); + }, + + /** */ + setFontStyle(value, updateModel) { + const textShape = this.getTextShape(); + textShape.setStyle(value); + if ($defined(updateModel) && updateModel) { + const model = this.getModel(); + model.setFontStyle(value); + } + this._adjustShapes(updateModel); + }, + + /** */ + setFontWeight(value, updateModel) { + const textShape = this.getTextShape(); + textShape.setWeight(value); + if ($defined(updateModel) && updateModel) { + const model = this.getModel(); + model.setFontWeight(value); + } + this._adjustShapes(); + }, + + /** */ + getFontWeight() { + const model = this.getModel(); + let result = model.getFontWeight(); + if (!$defined(result)) { + const font = TopicStyle.defaultFontStyle(this); + result = font.weight; + } + return result; + }, + + /** */ + getFontFamily() { + const model = this.getModel(); + let result = model.getFontFamily(); + if (!$defined(result)) { + const font = TopicStyle.defaultFontStyle(this); + result = font.font; + } + return result; + }, + + /** */ + getFontColor() { + const model = this.getModel(); + let result = model.getFontColor(); + if (!$defined(result)) { + const font = TopicStyle.defaultFontStyle(this); + result = font.color; + } + return result; + }, + + /** */ + getFontStyle() { + const model = this.getModel(); + let result = model.getFontStyle(); + if (!$defined(result)) { + const font = TopicStyle.defaultFontStyle(this); + result = font.style; + } + return result; + }, + + /** */ + getFontSize() { + const model = this.getModel(); + let result = model.getFontSize(); + if (!$defined(result)) { + const font = TopicStyle.defaultFontStyle(this); + result = font.size; + } + return result; + }, + + /** */ + setFontColor(value, updateModel) { + const textShape = this.getTextShape(); + textShape.setColor(value); + if ($defined(updateModel) && updateModel) { + const model = this.getModel(); + model.setFontColor(value); + } + }, + + _setText(text, updateModel) { + const textShape = this.getTextShape(); + textShape.setText(text == null ? TopicStyle.defaultText(this) : text); + + if ($defined(updateModel) && updateModel) { + const model = this.getModel(); + model.setText(text); + } + }, + + /** */ + setText(text) { + // Avoid empty nodes ... + if (!text || $.trim(text).length == 0) { + text = null; + } + + this._setText(text, true); + this._adjustShapes(); + }, + + /** */ + getText() { + const model = this.getModel(); + let result = model.getText(); + if (!$defined(result)) { + result = TopicStyle.defaultText(this); + } + return result; + }, + + /** */ + setBackgroundColor(color) { + this._setBackgroundColor(color, true); + }, + + _setBackgroundColor(color, updateModel) { + const innerShape = this.getInnerShape(); + innerShape.setFill(color); + + const connector = this.getShrinkConnector(); + if (connector) { + connector.setFill(color); + } + + if ($defined(updateModel) && updateModel) { + const model = this.getModel(); + model.setBackgroundColor(color); + } + }, + + /** */ + getBackgroundColor() { + const model = this.getModel(); + let result = model.getBackgroundColor(); + if (!$defined(result)) { + result = TopicStyle.defaultBackgroundColor(this); + } + return result; + }, + + /** */ + setBorderColor(color) { + this._setBorderColor(color, true); + }, + + _setBorderColor(color, updateModel) { + const innerShape = this.getInnerShape(); + innerShape.setAttribute('strokeColor', color); + + const connector = this.getShrinkConnector(); + if (connector) { + connector.setAttribute('strokeColor', color); + } + + if ($defined(updateModel) && updateModel) { + const model = this.getModel(); + model.setBorderColor(color); + } + }, + + /** */ + getBorderColor() { + const model = this.getModel(); + let result = model.getBorderColor(); + if (!$defined(result)) { + result = TopicStyle.defaultBorderColor(this); + } + return result; + }, + + _buildTopicShape() { + const groupAttributes = { + width: 100, + height: 100, + coordSizeWidth: 100, + coordSizeHeight: 100, + }; + const group = new web2d.Group(groupAttributes); + this._set2DElement(group); + + // Shape must be build based on the model width ... + const outerShape = this.getOuterShape(); + const innerShape = this.getInnerShape(); + const textShape = this.getTextShape(); + + // Add to the group ... + group.append(outerShape); + group.append(innerShape); + group.append(textShape); + + // Update figure size ... + const model = this.getModel(); + if (model.getFeatures().length != 0) { + this.getOrBuildIconGroup(); + } + + const shrinkConnector = this.getShrinkConnector(); + if ($defined(shrinkConnector)) { + shrinkConnector.addToWorkspace(group); + } + + // Register listeners ... + this._registerDefaultListenersToElement(group, this); + }, + + _registerDefaultListenersToElement(elem, topic) { + const mouseOver = function (event) { + if (topic.isMouseEventsEnabled()) { + topic.handleMouseOver(event); + } + }; + elem.addEvent('mouseover', mouseOver); + + const outout = function (event) { + if (topic.isMouseEventsEnabled()) { + topic.handleMouseOut(event); + } + }; + elem.addEvent('mouseout', outout); + + const me = this; + // Focus events ... + elem.addEvent('mousedown', (event) => { + if (!me.isReadOnly()) { + // Disable topic selection of readOnly mode ... + let value = true; + if ( + (event.metaKey && Browser.Platform.mac) + || (event.ctrlKey && !Browser.Platform.mac) + ) { + value = !me.isOnFocus(); + event.stopPropagation(); + event.preventDefault(); + } + topic.setOnFocus(value); + } + + const eventDispatcher = me._getTopicEventDispatcher(); + eventDispatcher.process(TopicEvent.CLICK, me); + event.stopPropagation(); + }); + }, + + /** */ + areChildrenShrunken() { + const model = this.getModel(); + return model.areChildrenShrunken() && !this.isCentralTopic(); + }, + + /** */ + isCollapsed() { + let result = false; + + let current = this.getParent(); + while (current && !result) { + result = current.areChildrenShrunken(); + current = current.getParent(); + } + return result; + }, + + /** */ + setChildrenShrunken(value) { + // Update Model ... + const model = this.getModel(); + model.setChildrenShrunken(value); + + // Change render base on the state. + const shrinkConnector = this.getShrinkConnector(); + if ($defined(shrinkConnector)) { + shrinkConnector.changeRender(value); + } + + // Do some fancy animation .... + const elements = this._flatten2DElements(this); + const fade = new FadeEffect(elements, !value); + const me = this; + fade.addEvent('complete', () => { + // Set focus on the parent node ... + if (value) { + me.setOnFocus(true); + } + + // Set focus in false for all the children ... + elements.forEach((elem) => { + if (elem.setOnFocus) { + elem.setOnFocus(false); + } + }); + }); + fade.start(); + + EventBus.instance.fireEvent(EventBus.events.NodeShrinkEvent, model); + }, + + /** */ + getShrinkConnector() { + let result = this._connector; + if (this._connector == null) { + this._connector = new ShirinkConnector(this); + this._connector.setVisibility(false); + result = this._connector; + } + return result; + }, + + /** */ + handleMouseOver() { + const outerShape = this.getOuterShape(); + outerShape.setOpacity(1); + }, + + /** */ + handleMouseOut() { + const outerShape = this.getOuterShape(); + if (!this.isOnFocus()) { + outerShape.setOpacity(0); + } + }, + + /** */ + showTextEditor(text) { + this._getTopicEventDispatcher().show(this, { text }); + }, + + /** */ + showNoteEditor() { + const topicId = this.getId(); + const model = this.getModel(); + const editorModel = { + getValue() { + const notes = model.findFeatureByType(TopicFeature.Note.id); + let result; + if (notes.length > 0) result = notes[0].getText(); + + return result; }, - /** */ - findFeatureById: function (id) { - var model = this.getModel(); - return model.findFeatureById(id); - }, - - /** */ - removeFeature: function (featureModel) { - $assert(featureModel, 'featureModel could not be null'); - - //Removing the icon from MODEL - var model = this.getModel(); - model.removeFeature(featureModel); - - //Removing the icon from UI - var iconGroup = this.getIconGroup(); - if ($defined(iconGroup)) { - iconGroup.removeIconByModel(featureModel); - } - this._adjustShapes(); - }, - - /** */ - addRelationship: function (relationship) { - this._relationships.push(relationship); - }, - - /** */ - deleteRelationship: function (relationship) { - this._relationships.erase(relationship); - }, - - /** */ - getRelationships: function () { - return this._relationships; - }, - - _buildTextShape: function (readOnly) { - var result = new web2d.Text(); - var family = this.getFontFamily(); - var size = this.getFontSize(); - var weight = this.getFontWeight(); - var style = this.getFontStyle(); - result.setFont(family, size, style, weight); - - var color = this.getFontColor(); - result.setColor(color); - - if (!readOnly) { - // Propagate mouse events ... - if (!this.isCentralTopic()) { - result.setCursor('move'); - } else { - result.setCursor('default'); - } - } - - return result; - }, - - /** */ - setFontFamily: function (value, updateModel) { - var textShape = this.getTextShape(); - textShape.setFontFamily(value); - if ($defined(updateModel) && updateModel) { - var model = this.getModel(); - model.setFontFamily(value); - } - this._adjustShapes(updateModel); - }, - - /** */ - setFontSize: function (value, updateModel) { - var textShape = this.getTextShape(); - textShape.setSize(value); - - if ($defined(updateModel) && updateModel) { - var model = this.getModel(); - model.setFontSize(value); - } - this._adjustShapes(updateModel); - }, - - /** */ - setFontStyle: function (value, updateModel) { - var textShape = this.getTextShape(); - textShape.setStyle(value); - if ($defined(updateModel) && updateModel) { - var model = this.getModel(); - model.setFontStyle(value); - } - this._adjustShapes(updateModel); - }, - - /** */ - setFontWeight: function (value, updateModel) { - var textShape = this.getTextShape(); - textShape.setWeight(value); - if ($defined(updateModel) && updateModel) { - var model = this.getModel(); - model.setFontWeight(value); - } - this._adjustShapes(); - }, - - /** */ - getFontWeight: function () { - var model = this.getModel(); - var result = model.getFontWeight(); - if (!$defined(result)) { - var font = TopicStyle.defaultFontStyle(this); - result = font.weight; - } - return result; - }, - - /** */ - getFontFamily: function () { - var model = this.getModel(); - var result = model.getFontFamily(); - if (!$defined(result)) { - var font = TopicStyle.defaultFontStyle(this); - result = font.font; - } - return result; - }, - - /** */ - getFontColor: function () { - var model = this.getModel(); - var result = model.getFontColor(); - if (!$defined(result)) { - var font = TopicStyle.defaultFontStyle(this); - result = font.color; - } - return result; - }, - - /** */ - getFontStyle: function () { - var model = this.getModel(); - var result = model.getFontStyle(); - if (!$defined(result)) { - var font = TopicStyle.defaultFontStyle(this); - result = font.style; - } - return result; - }, - - /** */ - getFontSize: function () { - var model = this.getModel(); - var result = model.getFontSize(); - if (!$defined(result)) { - var font = TopicStyle.defaultFontStyle(this); - result = font.size; - } - return result; - }, - - /** */ - setFontColor: function (value, updateModel) { - var textShape = this.getTextShape(); - textShape.setColor(value); - if ($defined(updateModel) && updateModel) { - var model = this.getModel(); - model.setFontColor(value); - } - }, - - _setText: function (text, updateModel) { - var textShape = this.getTextShape(); - textShape.setText(text == null ? TopicStyle.defaultText(this) : text); - - if ($defined(updateModel) && updateModel) { - var model = this.getModel(); - model.setText(text); - } - }, - - /** */ - setText: function (text) { - // Avoid empty nodes ... - if (!text || $.trim(text).length == 0) { - text = null; - } - - this._setText(text, true); - this._adjustShapes(); - }, - - /** */ - getText: function () { - var model = this.getModel(); - var result = model.getText(); - if (!$defined(result)) { - result = TopicStyle.defaultText(this); - } - return result; - }, - - /** */ - setBackgroundColor: function (color) { - this._setBackgroundColor(color, true); - }, - - _setBackgroundColor: function (color, updateModel) { - var innerShape = this.getInnerShape(); - innerShape.setFill(color); - - var connector = this.getShrinkConnector(); - if (connector) { - connector.setFill(color); - } - - if ($defined(updateModel) && updateModel) { - var model = this.getModel(); - model.setBackgroundColor(color); - } - }, - - /** */ - getBackgroundColor: function () { - var model = this.getModel(); - var result = model.getBackgroundColor(); - if (!$defined(result)) { - result = TopicStyle.defaultBackgroundColor(this); - } - return result; - }, - - /** */ - setBorderColor: function (color) { - this._setBorderColor(color, true); - }, - - _setBorderColor: function (color, updateModel) { - var innerShape = this.getInnerShape(); - innerShape.setAttribute('strokeColor', color); - - var connector = this.getShrinkConnector(); - if (connector) { - connector.setAttribute('strokeColor', color); - } - - if ($defined(updateModel) && updateModel) { - var model = this.getModel(); - model.setBorderColor(color); - } - }, - - /** */ - getBorderColor: function () { - var model = this.getModel(); - var result = model.getBorderColor(); - if (!$defined(result)) { - result = TopicStyle.defaultBorderColor(this); - } - return result; - }, - - _buildTopicShape: function () { - var groupAttributes = { - width: 100, - height: 100, - coordSizeWidth: 100, - coordSizeHeight: 100, - }; - var group = new web2d.Group(groupAttributes); - this._set2DElement(group); - - // Shape must be build based on the model width ... - var outerShape = this.getOuterShape(); - var innerShape = this.getInnerShape(); - var textShape = this.getTextShape(); - - // Add to the group ... - group.append(outerShape); - group.append(innerShape); - group.append(textShape); - - // Update figure size ... - var model = this.getModel(); - if (model.getFeatures().length != 0) { - this.getOrBuildIconGroup(); - } - - var shrinkConnector = this.getShrinkConnector(); - if ($defined(shrinkConnector)) { - shrinkConnector.addToWorkspace(group); - } - - // Register listeners ... - this._registerDefaultListenersToElement(group, this); - }, - - _registerDefaultListenersToElement: function (elem, topic) { - var mouseOver = function (event) { - if (topic.isMouseEventsEnabled()) { - topic.handleMouseOver(event); - } - }; - elem.addEvent('mouseover', mouseOver); - - var outout = function (event) { - if (topic.isMouseEventsEnabled()) { - topic.handleMouseOut(event); - } - }; - elem.addEvent('mouseout', outout); - - var me = this; - // Focus events ... - elem.addEvent('mousedown', function (event) { - if (!me.isReadOnly()) { - // Disable topic selection of readOnly mode ... - var value = true; - if ( - (event.metaKey && Browser.Platform.mac) || - (event.ctrlKey && !Browser.Platform.mac) - ) { - value = !me.isOnFocus(); - event.stopPropagation(); - event.preventDefault(); - } - topic.setOnFocus(value); - } - - var eventDispatcher = me._getTopicEventDispatcher(); - eventDispatcher.process(TopicEvent.CLICK, me); - event.stopPropagation(); + setValue(value) { + const dispatcher = ActionDispatcher.getInstance(); + const notes = model.findFeatureByType(TopicFeature.Note.id); + if (!$defined(value)) { + const featureId = notes[0].getId(); + dispatcher.removeFeatureFromTopic(topicId, featureId); + } else if (notes.length > 0) { + dispatcher.changeFeatureToTopic(topicId, notes[0].getId(), { + text: value, }); - }, - - /** */ - areChildrenShrunken: function () { - var model = this.getModel(); - return model.areChildrenShrunken() && !this.isCentralTopic(); - }, - - /** */ - isCollapsed: function () { - var result = false; - - var current = this.getParent(); - while (current && !result) { - result = current.areChildrenShrunken(); - current = current.getParent(); - } - return result; - }, - - /** */ - setChildrenShrunken: function (value) { - // Update Model ... - var model = this.getModel(); - model.setChildrenShrunken(value); - - // Change render base on the state. - var shrinkConnector = this.getShrinkConnector(); - if ($defined(shrinkConnector)) { - shrinkConnector.changeRender(value); - } - - // Do some fancy animation .... - var elements = this._flatten2DElements(this); - var fade = new FadeEffect(elements, !value); - var me = this; - fade.addEvent('complete', function () { - // Set focus on the parent node ... - if (value) { - me.setOnFocus(true); - } - - // Set focus in false for all the children ... - elements.forEach(function (elem) { - if (elem.setOnFocus) { - elem.setOnFocus(false); - } - }); + } else { + dispatcher.addFeatureToTopic(topicId, TopicFeature.Note.id, { + text: value, }); - fade.start(); + } + }, + }; + const editor = new NoteEditor(editorModel); + this.closeEditors(); + editor.show(); + }, - EventBus.instance.fireEvent(EventBus.events.NodeShrinkEvent, model); + /** opens a dialog where the user can enter or edit an existing link associated with this topic */ + showLinkEditor() { + const topicId = this.getId(); + const model = this.getModel(); + const editorModel = { + getValue() { + // @param {mindplot.model.LinkModel[]} links + const links = model.findFeatureByType(TopicFeature.Link.id); + let result; + if (links.length > 0) result = links[0].getUrl(); + + return result; }, - /** */ - getShrinkConnector: function () { - var result = this._connector; - if (this._connector == null) { - this._connector = new ShirinkConnector(this); - this._connector.setVisibility(false); - result = this._connector; - } - return result; + setValue(value) { + const dispatcher = ActionDispatcher.getInstance(); + const links = model.findFeatureByType(TopicFeature.Link.id); + if (!$defined(value)) { + const featureId = links[0].getId(); + dispatcher.removeFeatureFromTopic(topicId, featureId); + } else if (links.length > 0) { + dispatcher.changeFeatureToTopic(topicId, links[0].getId(), { + url: value, + }); + } else { + dispatcher.addFeatureToTopic(topicId, TopicFeature.Link.id, { + url: value, + }); + } }, + }; - /** */ - handleMouseOver: function () { - var outerShape = this.getOuterShape(); - outerShape.setOpacity(1); - }, + this.closeEditors(); + const editor = new LinkEditor(editorModel); + editor.show(); + }, - /** */ - handleMouseOut: function () { - var outerShape = this.getOuterShape(); - if (!this.isOnFocus()) { - outerShape.setOpacity(0); - } - }, + /** */ + closeEditors() { + this._getTopicEventDispatcher().close(true); + }, - /** */ - showTextEditor: function (text) { - this._getTopicEventDispatcher().show(this, { text: text }); - }, + _getTopicEventDispatcher() { + return TopicEventDispatcher.getInstance(); + }, - /** */ - showNoteEditor: function () { - var topicId = this.getId(); - var model = this.getModel(); - var editorModel = { - getValue: function () { - var notes = model.findFeatureByType(TopicFeature.Note.id); - var result; - if (notes.length > 0) result = notes[0].getText(); - - return result; - }, - - setValue: function (value) { - var dispatcher = ActionDispatcher.getInstance(); - var notes = model.findFeatureByType(TopicFeature.Note.id); - if (!$defined(value)) { - var featureId = notes[0].getId(); - dispatcher.removeFeatureFromTopic(topicId, featureId); - } else { - if (notes.length > 0) { - dispatcher.changeFeatureToTopic(topicId, notes[0].getId(), { - text: value, - }); - } else { - dispatcher.addFeatureToTopic(topicId, TopicFeature.Note.id, { - text: value, - }); - } - } - }, - }; - var editor = new NoteEditor(editorModel); - this.closeEditors(); - editor.show(); - }, - - /** opens a dialog where the user can enter or edit an existing link associated with this topic */ - showLinkEditor: function () { - var topicId = this.getId(); - var model = this.getModel(); - var editorModel = { - getValue: function () { - //@param {mindplot.model.LinkModel[]} links - var links = model.findFeatureByType(TopicFeature.Link.id); - var result; - if (links.length > 0) result = links[0].getUrl(); - - return result; - }, - - setValue: function (value) { - var dispatcher = ActionDispatcher.getInstance(); - var links = model.findFeatureByType(TopicFeature.Link.id); - if (!$defined(value)) { - var featureId = links[0].getId(); - dispatcher.removeFeatureFromTopic(topicId, featureId); - } else { - if (links.length > 0) { - dispatcher.changeFeatureToTopic(topicId, links[0].getId(), { - url: value, - }); - } else { - dispatcher.addFeatureToTopic(topicId, TopicFeature.Link.id, { - url: value, - }); - } - } - }, - }; - - this.closeEditors(); - var editor = new LinkEditor(editorModel); - editor.show(); - }, - - /** */ - closeEditors: function () { - this._getTopicEventDispatcher().close(true); - }, - - _getTopicEventDispatcher: function () { - return TopicEventDispatcher.getInstance(); - }, - - /** + /** * Point: references the center of the rect shape.!!! */ - setPosition: function (point) { - $assert(point, 'position can not be null'); - point.x = Math.ceil(point.x); - point.y = Math.ceil(point.y); - - // Update model's position ... - var model = this.getModel(); - model.setPosition(point.x, point.y); - - // Elements are positioned in the center. - // All topic element must be positioned based on the innerShape. - var size = this.getSize(); - - var cx = point.x - size.width / 2; - var cy = point.y - size.height / 2; - - // Update visual position. - this._elem2d.setPosition(cx, cy); - - // Update connection lines ... - this._updateConnectionLines(); - - // Check object state. - this.invariant(); - }, - - /** */ - getOutgoingLine: function () { - return this._outgoingLine; - }, - - /** */ - getIncomingLines: function () { - var result = []; - var children = this.getChildren(); - for (var i = 0; i < children.length; i++) { - var node = children[i]; - var line = node.getOutgoingLine(); - if ($defined(line)) { - result.push(line); - } - } - return result; - }, - - /** */ - getOutgoingConnectedTopic: function () { - var result = null; - var line = this.getOutgoingLine(); - if ($defined(line)) { - result = line.getTargetTopic(); - } - return result; - }, - - _updateConnectionLines: function () { - // Update this to parent line ... - var outgoingLine = this.getOutgoingLine(); - if ($defined(outgoingLine)) { - outgoingLine.redraw(); - } - - // Update all the incoming lines ... - var incomingLines = this.getIncomingLines(); - for (var i = 0; i < incomingLines.length; i++) { - incomingLines[i].redraw(); - } - - // Update relationship lines - for (var j = 0; j < this._relationships.length; j++) { - this._relationships[j].redraw(); - } - }, - - /** */ - setBranchVisibility: function (value) { - var current = this; - var parent = this; - while (parent != null && !parent.isCentralTopic()) { - current = parent; - parent = current.getParent(); - } - current.setVisibility(value); - }, - - /** */ - setVisibility: function (value) { - this._setTopicVisibility(value); - - // Hide all children... - this._setChildrenVisibility(value); - - // If there there are connection to the node, topic must be hidden. - this._setRelationshipLinesVisibility(value); - - // If it's connected, the connection must be rendered. - var outgoingLine = this.getOutgoingLine(); - if (outgoingLine) { - outgoingLine.setVisibility(value); - } - }, - - /** */ - moveToBack: function () { - // Update relationship lines - for (var j = 0; j < this._relationships.length; j++) { - this._relationships[j].moveToBack(); - } - var connector = this.getShrinkConnector(); - if ($defined(connector)) { - connector.moveToBack(); - } - - this.get2DElement().moveToBack(); - }, - - /** */ - moveToFront: function () { - this.get2DElement().moveToFront(); - var connector = this.getShrinkConnector(); - if ($defined(connector)) { - connector.moveToFront(); - } - // Update relationship lines - for (var j = 0; j < this._relationships.length; j++) { - this._relationships[j].moveToFront(); - } - }, - - /** */ - isVisible: function () { - var elem = this.get2DElement(); - return elem.isVisible(); - }, - - _setRelationshipLinesVisibility: function (value) { - _.each(this._relationships, function (relationship) { - var sourceTopic = relationship.getSourceTopic(); - var targetTopic = relationship.getTargetTopic(); - - var targetParent = targetTopic.getModel().getParent(); - var sourceParent = sourceTopic.getModel().getParent(); - relationship.setVisibility( - value && - (targetParent == null || !targetParent.areChildrenShrunken()) && - (sourceParent == null || !sourceParent.areChildrenShrunken()) - ); - }); - }, - - _setTopicVisibility: function (value) { - var elem = this.get2DElement(); - elem.setVisibility(value); - - if (this.getIncomingLines().length > 0) { - var connector = this.getShrinkConnector(); - if ($defined(connector)) { - connector.setVisibility(value); - } - } - - var textShape = this.getTextShape(); - textShape.setVisibility(this.getShapeType() != TopicShape.IMAGE ? value : false); - }, - - /** */ - setOpacity: function (opacity) { - var elem = this.get2DElement(); - elem.setOpacity(opacity); - - var connector = this.getShrinkConnector(); - if ($defined(connector)) { - connector.setOpacity(opacity); - } - var textShape = this.getTextShape(); - textShape.setOpacity(opacity); - }, - - _setChildrenVisibility: function (isVisible) { - // Hide all children. - var children = this.getChildren(); - var model = this.getModel(); - - isVisible = isVisible ? !model.areChildrenShrunken() : isVisible; - for (var i = 0; i < children.length; i++) { - var child = children[i]; - child.setVisibility(isVisible); - - var outgoingLine = child.getOutgoingLine(); - outgoingLine.setVisibility(isVisible); - } - }, - - /** */ - invariant: function () { - var line = this._outgoingLine; - var model = this.getModel(); - var isConnected = model.isConnected(); - - // Check consistency... - if ((isConnected && !line) || (!isConnected && line)) { - // $assert(false,'Illegal state exception.'); - } - }, - - /** */ - setSize: function (size, force) { - $assert(size, 'size can not be null'); - $assert($defined(size.width), 'size seem not to be a valid element'); - size = { width: Math.ceil(size.width), height: Math.ceil(size.height) }; - - var oldSize = this.getSize(); - var hasSizeChanged = oldSize.width != size.width || oldSize.height != size.height; - if (hasSizeChanged || force) { - NodeGraph.prototype.setSize.call(this, size); - - var outerShape = this.getOuterShape(); - var innerShape = this.getInnerShape(); - - outerShape.setSize(size.width + 4, size.height + 6); - innerShape.setSize(size.width, size.height); - - // Update the figure position(ej: central topic must be centered) and children position. - this._updatePositionOnChangeSize(oldSize, size); - - if (hasSizeChanged) { - EventBus.instance.fireEvent(EventBus.events.NodeResizeEvent, { - node: this.getModel(), - size: size, - }); - } - } - }, - - _updatePositionOnChangeSize: function () { - $assert(false, 'this method must be overwrited.'); - }, - - /** */ - disconnect: function (workspace) { - var outgoingLine = this.getOutgoingLine(); - if ($defined(outgoingLine)) { - $assert(workspace, 'workspace can not be null'); - - this._outgoingLine = null; - - // Disconnect nodes ... - var targetTopic = outgoingLine.getTargetTopic(); - targetTopic.removeChild(this); - - // Update model ... - var childModel = this.getModel(); - childModel.disconnect(); - - this._parent = null; - - // Remove graphical element from the workspace... - outgoingLine.removeFromWorkspace(workspace); - - // Remove from workspace. - EventBus.instance.fireEvent(EventBus.events.NodeDisconnectEvent, this.getModel()); - - // Change text based on the current connection ... - var model = this.getModel(); - if (!model.getText()) { - var text = this.getText(); - this._setText(text, false); - } - if (!model.getFontSize()) { - var size = this.getFontSize(); - this.setFontSize(size, false); - } - - // Hide connection line?. - if (targetTopic.getChildren().length == 0) { - var connector = targetTopic.getShrinkConnector(); - if ($defined(connector)) { - connector.setVisibility(false); - } - } - } - }, - - /** */ - getOrder: function () { - var model = this.getModel(); - return model.getOrder(); - }, - - /** */ - setOrder: function (value) { - var model = this.getModel(); - model.setOrder(value); - }, - - /** */ - connectTo: function (targetTopic, workspace) { - $assert(!this._outgoingLine, 'Could not connect an already connected node'); - $assert(targetTopic != this, 'Circular connection are not allowed'); - $assert(targetTopic, 'Parent Graph can not be null'); - $assert(workspace, 'Workspace can not be null'); - - // Connect Graphical Nodes ... - targetTopic.append(this); - this._parent = targetTopic; - - // Update model ... - var targetModel = targetTopic.getModel(); - var childModel = this.getModel(); - childModel.connectTo(targetModel); - - // Create a connection line ... - var outgoingLine = new ConnectionLine(this, targetTopic); - outgoingLine.setVisibility(false); - - this._outgoingLine = outgoingLine; - workspace.append(outgoingLine); - - // Update figure is necessary. - this.updateTopicShape(targetTopic); - - // Change text based on the current connection ... - var model = this.getModel(); - if (!model.getText()) { - var text = this.getText(); - this._setText(text, false); - } - if (!model.getFontSize()) { - var size = this.getFontSize(); - this.setFontSize(size, false); - } - this.getTextShape(); - - // Display connection node... - var connector = targetTopic.getShrinkConnector(); - if ($defined(connector)) { - connector.setVisibility(true); - } - - // Redraw line ... - outgoingLine.redraw(); - - // Fire connection event ... - if (this.isInWorkspace()) { - EventBus.instance.fireEvent(EventBus.events.NodeConnectEvent, { - parentNode: targetTopic.getModel(), - childNode: this.getModel(), - }); - } - }, - - /** */ - append: function (child) { - var children = this.getChildren(); - children.push(child); - }, - - /** */ - removeChild: function (child) { - var children = this.getChildren(); - children.erase(child); - }, - - /** */ - getChildren: function () { - var result = this._children; - if (!$defined(result)) { - this._children = []; - result = this._children; - } - return result; - }, - - /** */ - removeFromWorkspace: function (workspace) { - var elem2d = this.get2DElement(); - workspace.removeChild(elem2d); - var line = this.getOutgoingLine(); - if ($defined(line)) { - workspace.removeChild(line); - } - this._isInWorkspace = false; - EventBus.instance.fireEvent(EventBus.events.NodeRemoved, this.getModel()); - }, - - /** */ - addToWorkspace: function (workspace) { - var elem = this.get2DElement(); - workspace.append(elem); - if (!this.isInWorkspace()) { - if (!this.isCentralTopic()) { - EventBus.instance.fireEvent(EventBus.events.NodeAdded, this.getModel()); - } - - if (this.getModel().isConnected()) - EventBus.instance.fireEvent(EventBus.events.NodeConnectEvent, { - parentNode: this.getOutgoingConnectedTopic().getModel(), - childNode: this.getModel(), - }); - } - this._isInWorkspace = true; - this._adjustShapes(); - }, - - /** */ - isInWorkspace: function () { - return this._isInWorkspace; - }, - - /** */ - createDragNode: function (layoutManager) { - var result = this.parent(layoutManager); - - // Is the node already connected ? - var targetTopic = this.getOutgoingConnectedTopic(); - if ($defined(targetTopic)) { - result.connectTo(targetTopic); - result.setVisibility(false); - } - - // If a drag node is create for it, let's hide the editor. - this._getTopicEventDispatcher().close(); - - return result; - }, - - _adjustShapes: function () { - if (this._isInWorkspace) { - var textShape = this.getTextShape(); - if (this.getShapeType() != TopicShape.IMAGE) { - var textWidth = textShape.getWidth(); - - var textHeight = textShape.getHeight(); - textHeight = textHeight != 0 ? textHeight : 20; - - var topicPadding = TopicStyle.getInnerPadding(this); - - // Adjust the icon size to the size of the text ... - var iconGroup = this.getOrBuildIconGroup(); - var fontHeight = this.getTextShape().getFontHeight(); - iconGroup.setPosition(topicPadding, topicPadding); - iconGroup.seIconSize(fontHeight, fontHeight); - - // Add a extra padding between the text and the icons - var iconsWidth = iconGroup.getSize().width; - if (iconsWidth != 0) { - iconsWidth = iconsWidth + textHeight / 4; - } - - var height = textHeight + topicPadding * 2; - var width = textWidth + iconsWidth + topicPadding * 2; - - this.setSize({ width: width, height: height }); - - // Position node ... - textShape.setPosition(topicPadding + iconsWidth, topicPadding); - } else { - // In case of images, the size if fixed ... - var size = this.getModel().getImageSize(); - this.setSize(size); - } - } - }, - - _flatten2DElements: function (topic) { - var result = []; - - var children = topic.getChildren(); - for (var i = 0; i < children.length; i++) { - var child = children[i]; - result.push(child); - result.push(child.getOutgoingLine()); - - var relationships = child.getRelationships(); - result = result.concat(relationships); - - if (!child.areChildrenShrunken()) { - var innerChilds = this._flatten2DElements(child); - result = result.concat(innerChilds); - } - } - return result; - }, - - /** + setPosition(point) { + $assert(point, 'position can not be null'); + point.x = Math.ceil(point.x); + point.y = Math.ceil(point.y); + + // Update model's position ... + const model = this.getModel(); + model.setPosition(point.x, point.y); + + // Elements are positioned in the center. + // All topic element must be positioned based on the innerShape. + const size = this.getSize(); + + const cx = point.x - size.width / 2; + const cy = point.y - size.height / 2; + + // Update visual position. + this._elem2d.setPosition(cx, cy); + + // Update connection lines ... + this._updateConnectionLines(); + + // Check object state. + this.invariant(); + }, + + /** */ + getOutgoingLine() { + return this._outgoingLine; + }, + + /** */ + getIncomingLines() { + const result = []; + const children = this.getChildren(); + for (let i = 0; i < children.length; i++) { + const node = children[i]; + const line = node.getOutgoingLine(); + if ($defined(line)) { + result.push(line); + } + } + return result; + }, + + /** */ + getOutgoingConnectedTopic() { + let result = null; + const line = this.getOutgoingLine(); + if ($defined(line)) { + result = line.getTargetTopic(); + } + return result; + }, + + _updateConnectionLines() { + // Update this to parent line ... + const outgoingLine = this.getOutgoingLine(); + if ($defined(outgoingLine)) { + outgoingLine.redraw(); + } + + // Update all the incoming lines ... + const incomingLines = this.getIncomingLines(); + for (let i = 0; i < incomingLines.length; i++) { + incomingLines[i].redraw(); + } + + // Update relationship lines + for (let j = 0; j < this._relationships.length; j++) { + this._relationships[j].redraw(); + } + }, + + /** */ + setBranchVisibility(value) { + let current = this; + let parent = this; + while (parent != null && !parent.isCentralTopic()) { + current = parent; + parent = current.getParent(); + } + current.setVisibility(value); + }, + + /** */ + setVisibility(value) { + this._setTopicVisibility(value); + + // Hide all children... + this._setChildrenVisibility(value); + + // If there there are connection to the node, topic must be hidden. + this._setRelationshipLinesVisibility(value); + + // If it's connected, the connection must be rendered. + const outgoingLine = this.getOutgoingLine(); + if (outgoingLine) { + outgoingLine.setVisibility(value); + } + }, + + /** */ + moveToBack() { + // Update relationship lines + for (let j = 0; j < this._relationships.length; j++) { + this._relationships[j].moveToBack(); + } + const connector = this.getShrinkConnector(); + if ($defined(connector)) { + connector.moveToBack(); + } + + this.get2DElement().moveToBack(); + }, + + /** */ + moveToFront() { + this.get2DElement().moveToFront(); + const connector = this.getShrinkConnector(); + if ($defined(connector)) { + connector.moveToFront(); + } + // Update relationship lines + for (let j = 0; j < this._relationships.length; j++) { + this._relationships[j].moveToFront(); + } + }, + + /** */ + isVisible() { + const elem = this.get2DElement(); + return elem.isVisible(); + }, + + _setRelationshipLinesVisibility(value) { + _.each(this._relationships, (relationship) => { + const sourceTopic = relationship.getSourceTopic(); + const targetTopic = relationship.getTargetTopic(); + + const targetParent = targetTopic.getModel().getParent(); + const sourceParent = sourceTopic.getModel().getParent(); + relationship.setVisibility( + value + && (targetParent == null || !targetParent.areChildrenShrunken()) + && (sourceParent == null || !sourceParent.areChildrenShrunken()), + ); + }); + }, + + _setTopicVisibility(value) { + const elem = this.get2DElement(); + elem.setVisibility(value); + + if (this.getIncomingLines().length > 0) { + const connector = this.getShrinkConnector(); + if ($defined(connector)) { + connector.setVisibility(value); + } + } + + const textShape = this.getTextShape(); + textShape.setVisibility(this.getShapeType() != TopicShape.IMAGE ? value : false); + }, + + /** */ + setOpacity(opacity) { + const elem = this.get2DElement(); + elem.setOpacity(opacity); + + const connector = this.getShrinkConnector(); + if ($defined(connector)) { + connector.setOpacity(opacity); + } + const textShape = this.getTextShape(); + textShape.setOpacity(opacity); + }, + + _setChildrenVisibility(isVisible) { + // Hide all children. + const children = this.getChildren(); + const model = this.getModel(); + + isVisible = isVisible ? !model.areChildrenShrunken() : isVisible; + for (let i = 0; i < children.length; i++) { + const child = children[i]; + child.setVisibility(isVisible); + + const outgoingLine = child.getOutgoingLine(); + outgoingLine.setVisibility(isVisible); + } + }, + + /** */ + invariant() { + const line = this._outgoingLine; + const model = this.getModel(); + const isConnected = model.isConnected(); + + // Check consistency... + if ((isConnected && !line) || (!isConnected && line)) { + // $assert(false,'Illegal state exception.'); + } + }, + + /** */ + setSize(size, force) { + $assert(size, 'size can not be null'); + $assert($defined(size.width), 'size seem not to be a valid element'); + size = { width: Math.ceil(size.width), height: Math.ceil(size.height) }; + + const oldSize = this.getSize(); + const hasSizeChanged = oldSize.width != size.width || oldSize.height != size.height; + if (hasSizeChanged || force) { + NodeGraph.prototype.setSize.call(this, size); + + const outerShape = this.getOuterShape(); + const innerShape = this.getInnerShape(); + + outerShape.setSize(size.width + 4, size.height + 6); + innerShape.setSize(size.width, size.height); + + // Update the figure position(ej: central topic must be centered) and children position. + this._updatePositionOnChangeSize(oldSize, size); + + if (hasSizeChanged) { + EventBus.instance.fireEvent(EventBus.events.NodeResizeEvent, { + node: this.getModel(), + size, + }); + } + } + }, + + _updatePositionOnChangeSize() { + $assert(false, 'this method must be overwrited.'); + }, + + /** */ + disconnect(workspace) { + const outgoingLine = this.getOutgoingLine(); + if ($defined(outgoingLine)) { + $assert(workspace, 'workspace can not be null'); + + this._outgoingLine = null; + + // Disconnect nodes ... + const targetTopic = outgoingLine.getTargetTopic(); + targetTopic.removeChild(this); + + // Update model ... + const childModel = this.getModel(); + childModel.disconnect(); + + this._parent = null; + + // Remove graphical element from the workspace... + outgoingLine.removeFromWorkspace(workspace); + + // Remove from workspace. + EventBus.instance.fireEvent(EventBus.events.NodeDisconnectEvent, this.getModel()); + + // Change text based on the current connection ... + const model = this.getModel(); + if (!model.getText()) { + const text = this.getText(); + this._setText(text, false); + } + if (!model.getFontSize()) { + const size = this.getFontSize(); + this.setFontSize(size, false); + } + + // Hide connection line?. + if (targetTopic.getChildren().length == 0) { + const connector = targetTopic.getShrinkConnector(); + if ($defined(connector)) { + connector.setVisibility(false); + } + } + } + }, + + /** */ + getOrder() { + const model = this.getModel(); + return model.getOrder(); + }, + + /** */ + setOrder(value) { + const model = this.getModel(); + model.setOrder(value); + }, + + /** */ + connectTo(targetTopic, workspace) { + $assert(!this._outgoingLine, 'Could not connect an already connected node'); + $assert(targetTopic != this, 'Circular connection are not allowed'); + $assert(targetTopic, 'Parent Graph can not be null'); + $assert(workspace, 'Workspace can not be null'); + + // Connect Graphical Nodes ... + targetTopic.append(this); + this._parent = targetTopic; + + // Update model ... + const targetModel = targetTopic.getModel(); + const childModel = this.getModel(); + childModel.connectTo(targetModel); + + // Create a connection line ... + const outgoingLine = new ConnectionLine(this, targetTopic); + outgoingLine.setVisibility(false); + + this._outgoingLine = outgoingLine; + workspace.append(outgoingLine); + + // Update figure is necessary. + this.updateTopicShape(targetTopic); + + // Change text based on the current connection ... + const model = this.getModel(); + if (!model.getText()) { + const text = this.getText(); + this._setText(text, false); + } + if (!model.getFontSize()) { + const size = this.getFontSize(); + this.setFontSize(size, false); + } + this.getTextShape(); + + // Display connection node... + const connector = targetTopic.getShrinkConnector(); + if ($defined(connector)) { + connector.setVisibility(true); + } + + // Redraw line ... + outgoingLine.redraw(); + + // Fire connection event ... + if (this.isInWorkspace()) { + EventBus.instance.fireEvent(EventBus.events.NodeConnectEvent, { + parentNode: targetTopic.getModel(), + childNode: this.getModel(), + }); + } + }, + + /** */ + append(child) { + const children = this.getChildren(); + children.push(child); + }, + + /** */ + removeChild(child) { + const children = this.getChildren(); + children.erase(child); + }, + + /** */ + getChildren() { + let result = this._children; + if (!$defined(result)) { + this._children = []; + result = this._children; + } + return result; + }, + + /** */ + removeFromWorkspace(workspace) { + const elem2d = this.get2DElement(); + workspace.removeChild(elem2d); + const line = this.getOutgoingLine(); + if ($defined(line)) { + workspace.removeChild(line); + } + this._isInWorkspace = false; + EventBus.instance.fireEvent(EventBus.events.NodeRemoved, this.getModel()); + }, + + /** */ + addToWorkspace(workspace) { + const elem = this.get2DElement(); + workspace.append(elem); + if (!this.isInWorkspace()) { + if (!this.isCentralTopic()) { + EventBus.instance.fireEvent(EventBus.events.NodeAdded, this.getModel()); + } + + if (this.getModel().isConnected()) { + EventBus.instance.fireEvent(EventBus.events.NodeConnectEvent, { + parentNode: this.getOutgoingConnectedTopic().getModel(), + childNode: this.getModel(), + }); + } + } + this._isInWorkspace = true; + this._adjustShapes(); + }, + + /** */ + isInWorkspace() { + return this._isInWorkspace; + }, + + /** */ + createDragNode(layoutManager) { + const result = this.parent(layoutManager); + + // Is the node already connected ? + const targetTopic = this.getOutgoingConnectedTopic(); + if ($defined(targetTopic)) { + result.connectTo(targetTopic); + result.setVisibility(false); + } + + // If a drag node is create for it, let's hide the editor. + this._getTopicEventDispatcher().close(); + + return result; + }, + + _adjustShapes() { + if (this._isInWorkspace) { + const textShape = this.getTextShape(); + if (this.getShapeType() != TopicShape.IMAGE) { + const textWidth = textShape.getWidth(); + + let textHeight = textShape.getHeight(); + textHeight = textHeight != 0 ? textHeight : 20; + + const topicPadding = TopicStyle.getInnerPadding(this); + + // Adjust the icon size to the size of the text ... + const iconGroup = this.getOrBuildIconGroup(); + const fontHeight = this.getTextShape().getFontHeight(); + iconGroup.setPosition(topicPadding, topicPadding); + iconGroup.seIconSize(fontHeight, fontHeight); + + // Add a extra padding between the text and the icons + let iconsWidth = iconGroup.getSize().width; + if (iconsWidth != 0) { + iconsWidth += textHeight / 4; + } + + const height = textHeight + topicPadding * 2; + const width = textWidth + iconsWidth + topicPadding * 2; + + this.setSize({ width, height }); + + // Position node ... + textShape.setPosition(topicPadding + iconsWidth, topicPadding); + } else { + // In case of images, the size if fixed ... + const size = this.getModel().getImageSize(); + this.setSize(size); + } + } + }, + + _flatten2DElements(topic) { + let result = []; + + const children = topic.getChildren(); + for (let i = 0; i < children.length; i++) { + const child = children[i]; + result.push(child); + result.push(child.getOutgoingLine()); + + const relationships = child.getRelationships(); + result = result.concat(relationships); + + if (!child.areChildrenShrunken()) { + const innerChilds = this._flatten2DElements(child); + result = result.concat(innerChilds); + } + } + return result; + }, + + /** * @param childTopic * @return {Boolean} true if childtopic is a child topic of this topic or the topic itself */ - isChildTopic: function (childTopic) { - var result = this.getId() == childTopic.getId(); - if (!result) { - var children = this.getChildren(); - for (var i = 0; i < children.length; i++) { - var parent = children[i]; - result = parent.isChildTopic(childTopic); - if (result) { - break; - } - } - } - return result; - }, + isChildTopic(childTopic) { + let result = this.getId() == childTopic.getId(); + if (!result) { + const children = this.getChildren(); + for (let i = 0; i < children.length; i++) { + const parent = children[i]; + result = parent.isChildTopic(childTopic); + if (result) { + break; + } + } + } + return result; + }, - /** @return {Boolean} true if the topic is the central topic of the map */ - isCentralTopic: function () { - return this.getModel().getType() == INodeModel.CENTRAL_TOPIC_TYPE; - }, - } + /** @return {Boolean} true if the topic is the central topic of the map */ + isCentralTopic() { + return this.getModel().getType() == INodeModel.CENTRAL_TOPIC_TYPE; + }, + }, ); /** @@ -1348,10 +1346,10 @@ Topic.CONNECTOR_WIDTH = 6; * @default */ Topic.OUTER_SHAPE_ATTRIBUTES = { - fillColor: 'rgb(252,235,192)', - stroke: '1 dot rgb(241,163,39)', - x: 0, - y: 0, + fillColor: 'rgb(252,235,192)', + stroke: '1 dot rgb(241,163,39)', + x: 0, + y: 0, }; /** * @constant diff --git a/packages/mindplot/lib/components/TopicEventDispatcher.js b/packages/mindplot/lib/components/TopicEventDispatcher.js index 6f6974ea..e82bccf5 100644 --- a/packages/mindplot/lib/components/TopicEventDispatcher.js +++ b/packages/mindplot/lib/components/TopicEventDispatcher.js @@ -20,66 +20,66 @@ const MultilineTextEditor = require('./MultilineTextEditor').default; const { TopicShape } = require('./model/INodeModel'); const TopicEventDispatcher = new Class({ - Extends: Events, - Static: { - _instance: null, + Extends: Events, + Static: { + _instance: null, - configure: function (readOnly) { - this._instance = new TopicEventDispatcher(readOnly); - }, - - getInstance: function () { - return this._instance; - }, + configure(readOnly) { + this._instance = new TopicEventDispatcher(readOnly); }, - initialize: function (readOnly) { - this._readOnly = readOnly; - this._activeEditor = null; - this._multilineEditor = new MultilineTextEditor(); + getInstance() { + return this._instance; }, + }, - close: function (update) { - if (this.isVisible()) { - this._activeEditor.close(update); - this._activeEditor = null; - } - }, + initialize(readOnly) { + this._readOnly = readOnly; + this._activeEditor = null; + this._multilineEditor = new MultilineTextEditor(); + }, - show: function (topic, options) { - this.process(TopicEvent.EDIT, topic, options); - }, + close(update) { + if (this.isVisible()) { + this._activeEditor.close(update); + this._activeEditor = null; + } + }, - process: function (eventType, topic, options) { - $assert(eventType, 'eventType can not be null'); + show(topic, options) { + this.process(TopicEvent.EDIT, topic, options); + }, - // Close all previous open editor .... - if (this.isVisible()) { - this.close(); - } + process(eventType, topic, options) { + $assert(eventType, 'eventType can not be null'); - // Open the new editor ... - var model = topic.getModel(); - if ( - model.getShapeType() != TopicShape.IMAGE && - !this._readOnly && - eventType == TopicEvent.EDIT - ) { - this._multilineEditor.show(topic, options ? options.text : null); - this._activeEditor = this._multilineEditor; - } else { - this.fireEvent(eventType, { model: model, readOnly: this._readOnly }); - } - }, + // Close all previous open editor .... + if (this.isVisible()) { + this.close(); + } - isVisible: function () { - return this._activeEditor != null && this._activeEditor.isVisible(); - }, + // Open the new editor ... + const model = topic.getModel(); + if ( + model.getShapeType() != TopicShape.IMAGE + && !this._readOnly + && eventType == TopicEvent.EDIT + ) { + this._multilineEditor.show(topic, options ? options.text : null); + this._activeEditor = this._multilineEditor; + } else { + this.fireEvent(eventType, { model, readOnly: this._readOnly }); + } + }, + + isVisible() { + return this._activeEditor != null && this._activeEditor.isVisible(); + }, }); const TopicEvent = { - EDIT: 'editnode', - CLICK: 'clicknode', + EDIT: 'editnode', + CLICK: 'clicknode', }; export { TopicEvent }; diff --git a/packages/mindplot/lib/components/TopicFeature.js b/packages/mindplot/lib/components/TopicFeature.js index 84e718e1..1312349c 100644 --- a/packages/mindplot/lib/components/TopicFeature.js +++ b/packages/mindplot/lib/components/TopicFeature.js @@ -25,38 +25,36 @@ const NoteModel = require('./model/NoteModel').default; const NoteIcon = require('./NoteIcon').default; const TopicFeature = { - /** the icon object */ - Icon: { - id: IconModel.FEATURE_TYPE, - model: IconModel, - icon: ImageIcon - }, + /** the icon object */ + Icon: { + id: IconModel.FEATURE_TYPE, + model: IconModel, + icon: ImageIcon, + }, - /** the link object */ - Link: { - id: LinkModel.FEATURE_TYPE, - model: LinkModel, - icon: LinkIcon - }, + /** the link object */ + Link: { + id: LinkModel.FEATURE_TYPE, + model: LinkModel, + icon: LinkIcon, + }, - /** the note object */ - Note: { - id: NoteModel.FEATURE_TYPE, - model: NoteModel, - icon: NoteIcon - }, + /** the note object */ + Note: { + id: NoteModel.FEATURE_TYPE, + model: NoteModel, + icon: NoteIcon, + }, - /** + /** * @param id the feature metadata id * @return {Boolean} returns true if the given id is contained in the metadata array */ - isSupported: function (id) { - return TopicFeature._featuresMetadataById.some(function (elem) { - return elem.id == id; - }); - }, + isSupported(id) { + return TopicFeature._featuresMetadataById.some((elem) => elem.id == id); + }, - /** + /** * @param type * @param attributes * @throws will throw an error if type is null or undefined @@ -64,17 +62,15 @@ const TopicFeature = { * @return {mindplot.model.FeatureModel} a new instance of the feature model subclass matching * the topic feature */ - createModel: function (type, attributes) { - $assert(type, 'type can not be null'); - $assert(attributes, 'attributes can not be null'); + createModel(type, attributes) { + $assert(type, 'type can not be null'); + $assert(attributes, 'attributes can not be null'); - var model = TopicFeature._featuresMetadataById.filter(function (elem) { - return elem.id == type; - })[0].model; - return new model(attributes); - }, + const { model } = TopicFeature._featuresMetadataById.filter((elem) => elem.id == type)[0]; + return new model(attributes); + }, - /** + /** * @param {mindplot.Topic} topic * @param {mindplot.model.FeatureModel} model * @param {Boolean} readOnly true if the editor is running in read-only mode @@ -82,15 +78,13 @@ const TopicFeature = { * @throws will throw an error if model is null or undefined * @return {mindplot.Icon} a new instance of the icon subclass matching the topic feature */ - createIcon: function (topic, model, readOnly) { - $assert(topic, 'topic can not be null'); - $assert(model, 'model can not be null'); + createIcon(topic, model, readOnly) { + $assert(topic, 'topic can not be null'); + $assert(model, 'model can not be null'); - var icon = TopicFeature._featuresMetadataById.filter(function (elem) { - return elem.id == model.getType(); - })[0].icon; - return new icon(topic, model, readOnly); - } + const { icon } = TopicFeature._featuresMetadataById.filter((elem) => elem.id == model.getType())[0]; + return new icon(topic, model, readOnly); + }, }; TopicFeature._featuresMetadataById = [TopicFeature.Icon, TopicFeature.Link, TopicFeature.Note]; diff --git a/packages/mindplot/lib/components/TopicStyle.js b/packages/mindplot/lib/components/TopicStyle.js index 60079f94..9e34da5c 100644 --- a/packages/mindplot/lib/components/TopicStyle.js +++ b/packages/mindplot/lib/components/TopicStyle.js @@ -18,115 +18,115 @@ const { TopicShape } = require('./model/INodeModel'); const TopicStyle = new Class({ - Static: { - _getStyles: function (topic) { - $assert(topic, 'topic can not be null'); + Static: { + _getStyles(topic) { + $assert(topic, 'topic can not be null'); - var result; - if (topic.isCentralTopic()) { - result = TopicStyle.STYLES.CENTRAL_TOPIC; - } else { - var targetTopic = topic.getOutgoingConnectedTopic(); - if ($defined(targetTopic)) { - if (targetTopic.isCentralTopic()) { - result = TopicStyle.STYLES.MAIN_TOPIC; - } else { - result = TopicStyle.STYLES.SUB_TOPIC; - } - } else { - result = TopicStyle.STYLES.ISOLATED_TOPIC; - } - } - return result; - }, - - defaultText: function (topic) { - var msgKey = this._getStyles(topic).msgKey; - return $msg(msgKey); - }, - - defaultFontStyle: function (topic) { - return this._getStyles(topic).fontStyle; - }, - - defaultBackgroundColor: function (topic) { - return this._getStyles(topic).backgroundColor; - }, - - defaultBorderColor: function (topic) { - return this._getStyles(topic).borderColor; - }, - - getInnerPadding: function (topic) { - return this._getStyles(topic).innerPadding; - }, - - defaultShapeType: function (topic) { - return this._getStyles(topic).shapeType; - }, + let result; + if (topic.isCentralTopic()) { + result = TopicStyle.STYLES.CENTRAL_TOPIC; + } else { + const targetTopic = topic.getOutgoingConnectedTopic(); + if ($defined(targetTopic)) { + if (targetTopic.isCentralTopic()) { + result = TopicStyle.STYLES.MAIN_TOPIC; + } else { + result = TopicStyle.STYLES.SUB_TOPIC; + } + } else { + result = TopicStyle.STYLES.ISOLATED_TOPIC; + } + } + return result; }, + + defaultText(topic) { + const { msgKey } = this._getStyles(topic); + return $msg(msgKey); + }, + + defaultFontStyle(topic) { + return this._getStyles(topic).fontStyle; + }, + + defaultBackgroundColor(topic) { + return this._getStyles(topic).backgroundColor; + }, + + defaultBorderColor(topic) { + return this._getStyles(topic).borderColor; + }, + + getInnerPadding(topic) { + return this._getStyles(topic).innerPadding; + }, + + defaultShapeType(topic) { + return this._getStyles(topic).shapeType; + }, + }, }); TopicStyle.STYLES = { - CENTRAL_TOPIC: { - borderColor: 'rgb(57,113,177)', - backgroundColor: 'rgb(80,157,192)', - fontStyle: { - font: 'Verdana', - size: 10, - style: 'normal', - weight: 'bold', - color: '#ffffff', - }, - msgKey: 'CENTRAL_TOPIC', - innerPadding: 11, - shapeType: TopicShape.ROUNDED_RECT, + CENTRAL_TOPIC: { + borderColor: 'rgb(57,113,177)', + backgroundColor: 'rgb(80,157,192)', + fontStyle: { + font: 'Verdana', + size: 10, + style: 'normal', + weight: 'bold', + color: '#ffffff', }, + msgKey: 'CENTRAL_TOPIC', + innerPadding: 11, + shapeType: TopicShape.ROUNDED_RECT, + }, - MAIN_TOPIC: { - borderColor: 'rgb(2,59,185)', - backgroundColor: 'rgb(224,229,239)', - fontStyle: { - font: 'Arial', - size: 8, - style: 'normal', - weight: 'normal', - color: 'rgb(82,92,97)', - }, - msgKey: 'MAIN_TOPIC', - innerPadding: 3, - shapeType: TopicShape.LINE, + MAIN_TOPIC: { + borderColor: 'rgb(2,59,185)', + backgroundColor: 'rgb(224,229,239)', + fontStyle: { + font: 'Arial', + size: 8, + style: 'normal', + weight: 'normal', + color: 'rgb(82,92,97)', }, + msgKey: 'MAIN_TOPIC', + innerPadding: 3, + shapeType: TopicShape.LINE, + }, - SUB_TOPIC: { - borderColor: 'rgb(2,59,185)', - backgroundColor: 'rgb(224,229,239)', - fontStyle: { - font: 'Arial', - size: 6, - style: 'normal', - weight: 'normal', - color: 'rgb(82,92,97)', - }, - msgKey: 'SUB_TOPIC', - innerPadding: 3, - shapeType: TopicShape.LINE, + SUB_TOPIC: { + borderColor: 'rgb(2,59,185)', + backgroundColor: 'rgb(224,229,239)', + fontStyle: { + font: 'Arial', + size: 6, + style: 'normal', + weight: 'normal', + color: 'rgb(82,92,97)', }, + msgKey: 'SUB_TOPIC', + innerPadding: 3, + shapeType: TopicShape.LINE, + }, - ISOLATED_TOPIC: { - borderColor: 'rgb(2,59,185)', - backgroundColor: 'rgb(224,229,239)', - fontStyle: { - font: 'Verdana', - size: 8, - style: 'normal', - weight: 'normal', - color: 'rgb(82,92,97)', - }, - msgKey: 'ISOLATED_TOPIC', - innerPadding: 4, - shapeType: TopicShape.LINE, + ISOLATED_TOPIC: { + borderColor: 'rgb(2,59,185)', + backgroundColor: 'rgb(224,229,239)', + fontStyle: { + font: 'Verdana', + size: 8, + style: 'normal', + weight: 'normal', + color: 'rgb(82,92,97)', }, + msgKey: 'ISOLATED_TOPIC', + innerPadding: 4, + shapeType: TopicShape.LINE, + }, }; export default TopicStyle; diff --git a/packages/mindplot/lib/components/Workspace.js b/packages/mindplot/lib/components/Workspace.js index 571a9bbd..a975525f 100644 --- a/packages/mindplot/lib/components/Workspace.js +++ b/packages/mindplot/lib/components/Workspace.js @@ -1,229 +1,226 @@ -/* - * Copyright [2015] [wisemapping] - * - * Licensed under WiseMapping Public License, Version 1.0 (the "License"). - * It is basically the Apache License, Version 2.0 (the "License") plus the - * "powered by wisemapping" text requirement on every single page; - * you may not use this file except in compliance with the License. - * You may obtain a copy of the license at - * - * http://www.wisemapping.org/license - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -const web2D = require('@wismapping/web2d') -const web2d = web2D(); - -const Workspace = new Class({ - initialize: function (screenManager, zoom) { - // Create a suitable container ... - $assert(screenManager, 'Div container can not be null'); - $assert(zoom, 'zoom container can not be null'); - - this._zoom = zoom; - this._screenManager = screenManager; - - var divContainer = screenManager.getContainer(); - this._screenWidth = parseInt(divContainer.css('width')); - this._screenHeight = parseInt(divContainer.css('height')); - - // Initialize web2d workspace. - var workspace = this._createWorkspace(); - this._workspace = workspace; - - // Append to the workspace... - workspace.addItAsChildTo(divContainer); - this.setZoom(zoom, true); - - // Register drag events ... - this._registerDragEvents(); - this._eventsEnabled = true; - }, - - _createWorkspace: function () { - // Initialize workspace ... - var coordOriginX = -(this._screenWidth / 2); - var coordOriginY = -(this._screenHeight / 2); - - var workspaceProfile = { - width: this._screenWidth + "px", - height: this._screenHeight + "px", - coordSizeWidth: this._screenWidth, - coordSizeHeight: this._screenHeight, - coordOriginX: coordOriginX, - coordOriginY: coordOriginY, - fillColor: 'transparent', - strokeWidth: 0 - }; - web2d.Toolkit.init(); - return new web2d.Workspace(workspaceProfile); - }, - - append: function (shape) { - if ($defined(shape.addToWorkspace)) { - shape.addToWorkspace(this); - } else { - this._workspace.append(shape); - } - }, - - removeChild: function (shape) { - // Element is a node, not a web2d element? - if ($defined(shape.removeFromWorkspace)) { - shape.removeFromWorkspace(this); - } else { - this._workspace.removeChild(shape); - } - }, - - addEvent: function (type, listener) { - this._workspace.addEvent(type, listener); - }, - - removeEvent: function (type, listener) { - $assert(type, 'type can not be null'); - $assert(listener, 'listener can not be null'); - this._workspace.removeEvent(type, listener); - }, - - getSize: function () { - return this._workspace.getCoordSize(); - }, - - setZoom: function (zoom, center) { - this._zoom = zoom; - var workspace = this._workspace; - - // Update coord scale... - var coordWidth = zoom * this._screenWidth; - var coordHeight = zoom * this._screenHeight; - workspace.setCoordSize(coordWidth, coordHeight); - - // View port coords ... - if (this._viewPort) { - this._viewPort.width = this._viewPort.width * zoom; - this._viewPort.height = this._viewPort.height * zoom; - } - - // Center topic.... - var coordOriginX; - var coordOriginY; - - if (center) { - if (this._viewPort) { - coordOriginX = -(this._viewPort.width / 2); - coordOriginY = -(this._viewPort.height / 2); - } else { - coordOriginX = -(coordWidth / 2); - coordOriginY = -(coordHeight / 2); - } - } else { - var coordOrigin = workspace.getCoordOrigin(); - coordOriginX = coordOrigin.x; - coordOriginY = coordOrigin.y; - } - - workspace.setCoordOrigin(coordOriginX, coordOriginY); - - // Update screen. - this._screenManager.setOffset(coordOriginX, coordOriginY); - this._screenManager.setScale(zoom); - - // Some changes in the screen. Let's fire an update event... - this._screenManager.fireEvent('update'); - }, - - getScreenManager: function () { - return this._screenManager; - }, - - enableWorkspaceEvents: function (value) { - this._eventsEnabled = value; - }, - - isWorkspaceEventsEnabled: function () { - return this._eventsEnabled; - }, - - dumpNativeChart: function () { - return this._workspace.dumpNativeChart(); - }, - - _registerDragEvents: function () { - var workspace = this._workspace; - var screenManager = this._screenManager; - var mWorkspace = this; - var mouseDownListener = function (event) { - if (!$defined(workspace._mouseMoveListener)) { - if (mWorkspace.isWorkspaceEventsEnabled()) { - mWorkspace.enableWorkspaceEvents(false); - - var mouseDownPosition = screenManager.getWorkspaceMousePosition(event); - var originalCoordOrigin = workspace.getCoordOrigin(); - - var wasDragged = false; - workspace._mouseMoveListener = function (event) { - - var currentMousePosition = screenManager.getWorkspaceMousePosition(event); - - var offsetX = currentMousePosition.x - mouseDownPosition.x; - var coordOriginX = -offsetX + originalCoordOrigin.x; - - var offsetY = currentMousePosition.y - mouseDownPosition.y; - var coordOriginY = -offsetY + originalCoordOrigin.y; - - workspace.setCoordOrigin(coordOriginX, coordOriginY); - - // Change cursor. - if (Browser.firefox) { - window.document.body.style.cursor = "-moz-grabbing"; - } else { - window.document.body.style.cursor = "move"; - } - event.preventDefault(); - - // Fire drag event ... - screenManager.fireEvent('update'); - wasDragged = true; - - - }; - screenManager.addEvent('mousemove', workspace._mouseMoveListener); - - // Register mouse up listeners ... - workspace._mouseUpListener = function (event) { - - screenManager.removeEvent('mousemove', workspace._mouseMoveListener); - screenManager.removeEvent('mouseup', workspace._mouseUpListener); - workspace._mouseUpListener = null; - workspace._mouseMoveListener = null; - window.document.body.style.cursor = 'default'; - - // Update screen manager offset. - var coordOrigin = workspace.getCoordOrigin(); - screenManager.setOffset(coordOrigin.x, coordOrigin.y); - mWorkspace.enableWorkspaceEvents(true); - - if (!wasDragged) { - screenManager.fireEvent('click'); - } - }; - screenManager.addEvent('mouseup', workspace._mouseUpListener); - } - } else { - workspace._mouseUpListener(); - } - }; - screenManager.addEvent('mousedown', mouseDownListener); - }, - - setViewPort: function (size) { - this._viewPort = size; - } -}); - -export default Workspace; +/* + * Copyright [2015] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const web2D = require('@wismapping/web2d'); + +const web2d = web2D(); + +const Workspace = new Class({ + initialize(screenManager, zoom) { + // Create a suitable container ... + $assert(screenManager, 'Div container can not be null'); + $assert(zoom, 'zoom container can not be null'); + + this._zoom = zoom; + this._screenManager = screenManager; + + const divContainer = screenManager.getContainer(); + this._screenWidth = parseInt(divContainer.css('width')); + this._screenHeight = parseInt(divContainer.css('height')); + + // Initialize web2d workspace. + const workspace = this._createWorkspace(); + this._workspace = workspace; + + // Append to the workspace... + workspace.addItAsChildTo(divContainer); + this.setZoom(zoom, true); + + // Register drag events ... + this._registerDragEvents(); + this._eventsEnabled = true; + }, + + _createWorkspace() { + // Initialize workspace ... + const coordOriginX = -(this._screenWidth / 2); + const coordOriginY = -(this._screenHeight / 2); + + const workspaceProfile = { + width: `${this._screenWidth}px`, + height: `${this._screenHeight}px`, + coordSizeWidth: this._screenWidth, + coordSizeHeight: this._screenHeight, + coordOriginX, + coordOriginY, + fillColor: 'transparent', + strokeWidth: 0, + }; + web2d.Toolkit.init(); + return new web2d.Workspace(workspaceProfile); + }, + + append(shape) { + if ($defined(shape.addToWorkspace)) { + shape.addToWorkspace(this); + } else { + this._workspace.append(shape); + } + }, + + removeChild(shape) { + // Element is a node, not a web2d element? + if ($defined(shape.removeFromWorkspace)) { + shape.removeFromWorkspace(this); + } else { + this._workspace.removeChild(shape); + } + }, + + addEvent(type, listener) { + this._workspace.addEvent(type, listener); + }, + + removeEvent(type, listener) { + $assert(type, 'type can not be null'); + $assert(listener, 'listener can not be null'); + this._workspace.removeEvent(type, listener); + }, + + getSize() { + return this._workspace.getCoordSize(); + }, + + setZoom(zoom, center) { + this._zoom = zoom; + const workspace = this._workspace; + + // Update coord scale... + const coordWidth = zoom * this._screenWidth; + const coordHeight = zoom * this._screenHeight; + workspace.setCoordSize(coordWidth, coordHeight); + + // View port coords ... + if (this._viewPort) { + this._viewPort.width = this._viewPort.width * zoom; + this._viewPort.height = this._viewPort.height * zoom; + } + + // Center topic.... + let coordOriginX; + let coordOriginY; + + if (center) { + if (this._viewPort) { + coordOriginX = -(this._viewPort.width / 2); + coordOriginY = -(this._viewPort.height / 2); + } else { + coordOriginX = -(coordWidth / 2); + coordOriginY = -(coordHeight / 2); + } + } else { + const coordOrigin = workspace.getCoordOrigin(); + coordOriginX = coordOrigin.x; + coordOriginY = coordOrigin.y; + } + + workspace.setCoordOrigin(coordOriginX, coordOriginY); + + // Update screen. + this._screenManager.setOffset(coordOriginX, coordOriginY); + this._screenManager.setScale(zoom); + + // Some changes in the screen. Let's fire an update event... + this._screenManager.fireEvent('update'); + }, + + getScreenManager() { + return this._screenManager; + }, + + enableWorkspaceEvents(value) { + this._eventsEnabled = value; + }, + + isWorkspaceEventsEnabled() { + return this._eventsEnabled; + }, + + dumpNativeChart() { + return this._workspace.dumpNativeChart(); + }, + + _registerDragEvents() { + const workspace = this._workspace; + const screenManager = this._screenManager; + const mWorkspace = this; + const mouseDownListener = function (event) { + if (!$defined(workspace._mouseMoveListener)) { + if (mWorkspace.isWorkspaceEventsEnabled()) { + mWorkspace.enableWorkspaceEvents(false); + + const mouseDownPosition = screenManager.getWorkspaceMousePosition(event); + const originalCoordOrigin = workspace.getCoordOrigin(); + + let wasDragged = false; + workspace._mouseMoveListener = function (event) { + const currentMousePosition = screenManager.getWorkspaceMousePosition(event); + + const offsetX = currentMousePosition.x - mouseDownPosition.x; + const coordOriginX = -offsetX + originalCoordOrigin.x; + + const offsetY = currentMousePosition.y - mouseDownPosition.y; + const coordOriginY = -offsetY + originalCoordOrigin.y; + + workspace.setCoordOrigin(coordOriginX, coordOriginY); + + // Change cursor. + if (Browser.firefox) { + window.document.body.style.cursor = '-moz-grabbing'; + } else { + window.document.body.style.cursor = 'move'; + } + event.preventDefault(); + + // Fire drag event ... + screenManager.fireEvent('update'); + wasDragged = true; + }; + screenManager.addEvent('mousemove', workspace._mouseMoveListener); + + // Register mouse up listeners ... + workspace._mouseUpListener = function (event) { + screenManager.removeEvent('mousemove', workspace._mouseMoveListener); + screenManager.removeEvent('mouseup', workspace._mouseUpListener); + workspace._mouseUpListener = null; + workspace._mouseMoveListener = null; + window.document.body.style.cursor = 'default'; + + // Update screen manager offset. + const coordOrigin = workspace.getCoordOrigin(); + screenManager.setOffset(coordOrigin.x, coordOrigin.y); + mWorkspace.enableWorkspaceEvents(true); + + if (!wasDragged) { + screenManager.fireEvent('click'); + } + }; + screenManager.addEvent('mouseup', workspace._mouseUpListener); + } + } else { + workspace._mouseUpListener(); + } + }; + screenManager.addEvent('mousedown', mouseDownListener); + }, + + setViewPort(size) { + this._viewPort = size; + }, +}); + +export default Workspace; diff --git a/packages/mindplot/lib/components/commands/AddFeatureToTopicCommand.js b/packages/mindplot/lib/components/commands/AddFeatureToTopicCommand.js index 1bb35fc0..259ba865 100644 --- a/packages/mindplot/lib/components/commands/AddFeatureToTopicCommand.js +++ b/packages/mindplot/lib/components/commands/AddFeatureToTopicCommand.js @@ -18,8 +18,8 @@ const Command = require('../Command').default; const AddFeatureToTopicCommand = new Class(/** @lends AddFeatureToTopicCommand */{ - Extends: Command, - /** + Extends: Command, + /** * @classdesc This command class handles do/undo of adding features to topics, e.g. an * icon or a note. For a reference of existing features, refer to {@link mindplot.TopicFeature} * @constructs @@ -29,41 +29,40 @@ const AddFeatureToTopicCommand = new Class(/** @lends AddFeatureToTopicCommand * * @extends mindplot.Command * @see mindplot.model.FeatureModel and subclasses */ - initialize:function (topicId, featureType, attributes) { + initialize(topicId, featureType, attributes) { + $assert($defined(topicId), 'topicId can not be null'); + $assert(featureType, 'featureType can not be null'); + $assert(attributes, 'attributes can not be null'); - $assert($defined(topicId), 'topicId can not be null'); - $assert(featureType, 'featureType can not be null'); - $assert(attributes, 'attributes can not be null'); + this.parent(); + this._topicId = topicId; + this._featureType = featureType; + this._attributes = attributes; + this._featureModel = null; + }, - this.parent(); - this._topicId = topicId; - this._featureType = featureType; - this._attributes = attributes; - this._featureModel = null; - }, - - /** - * Overrides abstract parent method - */ - execute:function (commandContext) { - var topic = commandContext.findTopics(this._topicId)[0]; - - // Feature must be created only one time. - if (!this._featureModel) { - var model = topic.getModel(); - this._featureModel = model.createFeature(this._featureType, this._attributes); - } - topic.addFeature(this._featureModel); - }, - - /** + /** * Overrides abstract parent method - * @see {@link mindplot.Command.undoExecute} */ - undoExecute:function (commandContext) { - var topic = commandContext.findTopics(this._topicId)[0]; - topic.removeFeature(this._featureModel); + execute(commandContext) { + const topic = commandContext.findTopics(this._topicId)[0]; + + // Feature must be created only one time. + if (!this._featureModel) { + const model = topic.getModel(); + this._featureModel = model.createFeature(this._featureType, this._attributes); } + topic.addFeature(this._featureModel); + }, + + /** + * Overrides abstract parent method + * @see {@link mindplot.Command.undoExecute} + */ + undoExecute(commandContext) { + const topic = commandContext.findTopics(this._topicId)[0]; + topic.removeFeature(this._featureModel); + }, }); -export default AddFeatureToTopicCommand +export default AddFeatureToTopicCommand; diff --git a/packages/mindplot/lib/components/commands/AddRelationshipCommand.js b/packages/mindplot/lib/components/commands/AddRelationshipCommand.js index 879e454d..88180472 100644 --- a/packages/mindplot/lib/components/commands/AddRelationshipCommand.js +++ b/packages/mindplot/lib/components/commands/AddRelationshipCommand.js @@ -15,39 +15,39 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const Command = require('../Command').default +const Command = require('../Command').default; const AddRelationshipCommand = new Class(/** @lends AddRelationshipCommand */{ - Extends:Command, - /** + Extends: Command, + /** * @classdesc This command class handles do/undo of adding a relationship to a topic. * @constructs * @param {XMLDOM} model * @extends mindplot.Command */ - initialize:function (model) { - $assert(model, 'Relationship model can not be null'); + initialize(model) { + $assert(model, 'Relationship model can not be null'); - this.parent(); - this._model = model; - }, - - /** - * Overrides abstract parent method - */ - execute:function (commandContext) { - var relationship = commandContext.addRelationship(this._model); - relationship.setOnFocus(true); - }, + this.parent(); + this._model = model; + }, - /** + /** * Overrides abstract parent method - * @see {@link mindplot.Command.undoExecute} */ - undoExecute:function (commandContext) { - var rel = commandContext.findRelationships(this._model.getId()); - commandContext.deleteRelationship(rel[0]); - } + execute(commandContext) { + const relationship = commandContext.addRelationship(this._model); + relationship.setOnFocus(true); + }, + + /** + * Overrides abstract parent method + * @see {@link mindplot.Command.undoExecute} + */ + undoExecute(commandContext) { + const rel = commandContext.findRelationships(this._model.getId()); + commandContext.deleteRelationship(rel[0]); + }, }); export default AddRelationshipCommand; diff --git a/packages/mindplot/lib/components/commands/AddTopicCommand.js b/packages/mindplot/lib/components/commands/AddTopicCommand.js index efe49b39..76fde1f5 100644 --- a/packages/mindplot/lib/components/commands/AddTopicCommand.js +++ b/packages/mindplot/lib/components/commands/AddTopicCommand.js @@ -18,9 +18,9 @@ const Command = require('../Command').default; const AddTopicCommand = new Class( - /** @lends AddTopicCommand */ { - Extends: Command, - /** + /** @lends AddTopicCommand */ { + Extends: Command, + /** * @classdesc This command class handles do/undo of adding one or multiple topics to * the mindmap. * @constructs @@ -29,69 +29,69 @@ const AddTopicCommand = new Class( * when attaching a dragged node or a node/branch from clipboard * @extends mindplot.Command */ - initialize: function (models, parentTopicsId) { - $assert(models, 'models can not be null'); - $assert( - parentTopicsId == null || parentTopicsId.length == models.length, - 'parents and models must have the same size' - ); + initialize(models, parentTopicsId) { + $assert(models, 'models can not be null'); + $assert( + parentTopicsId == null || parentTopicsId.length == models.length, + 'parents and models must have the same size', + ); - this.parent(); - this._models = models; - this._parentsIds = parentTopicsId; - }, + this.parent(); + this._models = models; + this._parentsIds = parentTopicsId; + }, - /** + /** * Overrides abstract parent method */ - execute: function (commandContext) { - var me = this; - _.each(this._models, function (model, index) { - // Add a new topic ... - var topic = commandContext.createTopic(model); + execute(commandContext) { + const me = this; + _.each(this._models, (model, index) => { + // Add a new topic ... + const topic = commandContext.createTopic(model); - // Connect to topic ... - if (me._parentsIds) { - var parentId = me._parentsIds[index]; - if ($defined(parentId)) { - var parentTopic = commandContext.findTopics(parentId)[0]; - commandContext.connect(topic, parentTopic); - } - } else { - commandContext.addTopic(topic); - } + // Connect to topic ... + if (me._parentsIds) { + const parentId = me._parentsIds[index]; + if ($defined(parentId)) { + const parentTopic = commandContext.findTopics(parentId)[0]; + commandContext.connect(topic, parentTopic); + } + } else { + commandContext.addTopic(topic); + } - // Select just created node ... - var designer = commandContext._designer; - designer.onObjectFocusEvent(topic); - topic.setOnFocus(true); + // Select just created node ... + const designer = commandContext._designer; + designer.onObjectFocusEvent(topic); + topic.setOnFocus(true); - // Render node ... - topic.setVisibility(true); - }); - }, + // Render node ... + topic.setVisibility(true); + }); + }, - /** + /** * Overrides abstract parent method * @see {@link mindplot.Command.undoExecute} */ - undoExecute: function (commandContext) { - // Delete disconnected the nodes. Create a copy of the topics ... - var clonedModel = []; - _.each(this._models, function (model) { - clonedModel.push(model.clone()); - }); + undoExecute(commandContext) { + // Delete disconnected the nodes. Create a copy of the topics ... + const clonedModel = []; + _.each(this._models, (model) => { + clonedModel.push(model.clone()); + }); - // Finally, remove the nodes ... - _.each(this._models, function (model) { - var topicId = model.getId(); - var topic = commandContext.findTopics(topicId)[0]; - commandContext.deleteTopic(topic); - }); + // Finally, remove the nodes ... + _.each(this._models, (model) => { + const topicId = model.getId(); + const topic = commandContext.findTopics(topicId)[0]; + commandContext.deleteTopic(topic); + }); - this._models = clonedModel; - }, - } + this._models = clonedModel; + }, + }, ); export default AddTopicCommand; diff --git a/packages/mindplot/lib/components/commands/ChangeFeatureToTopicCommand.js b/packages/mindplot/lib/components/commands/ChangeFeatureToTopicCommand.js index 82ca6046..a5dc5625 100644 --- a/packages/mindplot/lib/components/commands/ChangeFeatureToTopicCommand.js +++ b/packages/mindplot/lib/components/commands/ChangeFeatureToTopicCommand.js @@ -15,11 +15,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const Command = require('../Command').default +const Command = require('../Command').default; const ChangeFeatureToTopicCommand = new Class(/** @lends ChangeFeatureToTopicCommand */{ - Extends:Command, - /** + Extends: Command, + /** * @extends mindplot.Command * @constructs * @param topicId @@ -29,36 +29,36 @@ const ChangeFeatureToTopicCommand = new Class(/** @lends ChangeFeatureToTopicCom * @throws will throw an error if featureId is null or undefined * @throws will throw an error if attributes is null or undefined */ - initialize: function(topicId, featureId, attributes) { - $assert($defined(topicId), 'topicId can not be null'); - $assert($defined(featureId), 'featureId can not be null'); - $assert($defined(attributes), 'attributes can not be null'); + initialize(topicId, featureId, attributes) { + $assert($defined(topicId), 'topicId can not be null'); + $assert($defined(featureId), 'featureId can not be null'); + $assert($defined(attributes), 'attributes can not be null'); - this.parent(); - this._topicId = topicId; - this._featureId = featureId; - this._attributes = attributes; - }, + this.parent(); + this._topicId = topicId; + this._featureId = featureId; + this._attributes = attributes; + }, - /** + /** * Overrides abstract parent method */ - execute: function(commandContext) { - var topic = commandContext.findTopics(this._topicId)[0]; - var feature = topic.findFeatureById(this._featureId); + execute(commandContext) { + const topic = commandContext.findTopics(this._topicId)[0]; + const feature = topic.findFeatureById(this._featureId); - var oldAttributes = feature.getAttributes(); - feature.setAttributes(this._attributes); - this._attributes = oldAttributes; - }, + const oldAttributes = feature.getAttributes(); + feature.setAttributes(this._attributes); + this._attributes = oldAttributes; + }, - /** + /** * Overrides abstract parent method * @see {@link mindplot.Command.undoExecute} */ - undoExecute: function(commandContext) { - this.execute(commandContext); - } + undoExecute(commandContext) { + this.execute(commandContext); + }, }); export default ChangeFeatureToTopicCommand; diff --git a/packages/mindplot/lib/components/commands/DeleteCommand.js b/packages/mindplot/lib/components/commands/DeleteCommand.js index 0e61c998..00d54c4b 100644 --- a/packages/mindplot/lib/components/commands/DeleteCommand.js +++ b/packages/mindplot/lib/components/commands/DeleteCommand.js @@ -18,169 +18,162 @@ const Command = require('../Command').default; const DeleteCommand = new Class(/** @lends mindplot.commands.DeleteCommand */{ - Extends:Command, - /** + Extends: Command, + /** * @classdesc This command class handles do/undo of deleting a topic. * @constructs * @param {Array} topicIds ids of the topics to delete * @param {Array} relIds ids of the relationships connected to the topics * @extends mindplot.Command */ - initialize:function (topicIds, relIds) { - $assert($defined(relIds), 'topicIds can not be null'); + initialize(topicIds, relIds) { + $assert($defined(relIds), 'topicIds can not be null'); - this.parent(); - this._relIds = relIds; - this._topicIds = topicIds; - this._deletedTopicModels = []; - this._deletedRelModel = []; - this._parentTopicIds = []; - }, + this.parent(); + this._relIds = relIds; + this._topicIds = topicIds; + this._deletedTopicModels = []; + this._deletedRelModel = []; + this._parentTopicIds = []; + }, - /** - * Overrides abstract parent method - */ - execute:function (commandContext) { - - // If a parent has been selected for deletion, the children must be excluded from the delete ... - var topics = this._filterChildren(this._topicIds, commandContext); - - if (topics.length > 0) { - _.each(topics, function (topic) { - // In case that it's editing text node, force close without update ... - topic.closeEditors(); - - var model = topic.getModel(); - - // Delete relationships - var relationships = this._collectInDepthRelationships(topic); - this._deletedRelModel.append(relationships.map(function (rel) { - return rel.getModel().clone(); - })); - - _.each(relationships, function (relationship) { - commandContext.deleteRelationship(relationship); - }); - - // Store information for undo ... - var clonedModel = model.clone(); - this._deletedTopicModels.push(clonedModel); - var outTopic = topic.getOutgoingConnectedTopic(); - var outTopicId = null; - if (outTopic != null) { - outTopicId = outTopic.getId(); - } - this._parentTopicIds.push(outTopicId); - - // Finally, delete the topic from the workspace... - commandContext.deleteTopic(topic); - - }, this); - } - - var rels = commandContext.findRelationships(this._relIds); - if (rels.length > 0) { - _.each(rels, function (rel) { - this._deletedRelModel.push(rel.getModel().clone()); - commandContext.deleteRelationship(rel); - }, this); - } - }, - - /** + /** * Overrides abstract parent method - * @see {@link mindplot.Command.undoExecute} */ - undoExecute:function (commandContext) { + execute(commandContext) { + // If a parent has been selected for deletion, the children must be excluded from the delete ... + const topics = this._filterChildren(this._topicIds, commandContext); - // Add all the topics ... - _.each(this._deletedTopicModels, function (model) { - commandContext.createTopic(model); - }, this); + if (topics.length > 0) { + _.each(topics, function (topic) { + // In case that it's editing text node, force close without update ... + topic.closeEditors(); - // Do they need to be connected ? - _.each(this._deletedTopicModels, function (topicModel, index) { - var topics = commandContext.findTopics(topicModel.getId()); + const model = topic.getModel(); - var parentId = this._parentTopicIds[index]; - if (parentId) { - var parentTopics = commandContext.findTopics(parentId); - commandContext.connect(topics[0], parentTopics[0]); - } - }, this); + // Delete relationships + const relationships = this._collectInDepthRelationships(topic); + this._deletedRelModel.append(relationships.map((rel) => rel.getModel().clone())); - // Add rebuild relationships ... - _.each(this._deletedRelModel, function (model) { - commandContext.addRelationship(model); + _.each(relationships, (relationship) => { + commandContext.deleteRelationship(relationship); }); - // Finally display the topics ... - _.each(this._deletedTopicModels, function (topicModel) { - var topics = commandContext.findTopics(topicModel.getId()); - topics[0].setBranchVisibility(true); - }, this); - - // Focus on last recovered topic .. - if (this._deletedTopicModels.length > 0) { - var firstTopic = this._deletedTopicModels[0]; - var topic = commandContext.findTopics(firstTopic.getId())[0]; - topic.setOnFocus(true); + // Store information for undo ... + const clonedModel = model.clone(); + this._deletedTopicModels.push(clonedModel); + const outTopic = topic.getOutgoingConnectedTopic(); + let outTopicId = null; + if (outTopic != null) { + outTopicId = outTopic.getId(); } + this._parentTopicIds.push(outTopicId); - this._deletedTopicModels = []; - this._parentTopicIds = []; - this._deletedRelModel = []; - }, - - _filterChildren:function (topicIds, commandContext) { - var topics = commandContext.findTopics(topicIds); - - var result = []; - _.each(topics, function (topic) { - var parent = topic.getParent(); - var found = false; - while (parent != null && !found) { - found = topicIds.contains(parent.getId()); - if (found) { - break; - } - parent = parent.getParent(); - } - - if (!found) { - result.push(topic); - } - }); - - return result; - }, - - _collectInDepthRelationships:function (topic) { - var result = []; - result.append(topic.getRelationships()); - - var children = topic.getChildren(); - var rels = children.map(function (topic) { - return this._collectInDepthRelationships(topic); - }, this); - result.append(rels.flatten()); - - if (result.length > 0) { - // Filter for unique ... - result = result.sort(function (a, b) { - return a.getModel().getId() - b.getModel().getId(); - }); - var ret = [result[0]]; - for (var i = 1; i < result.length; i++) { // start loop at 1 as element 0 can never be a duplicate - if (result[i - 1] !== result[i]) { - ret.push(result[i]); - } - } - result = ret; - } - return result; + // Finally, delete the topic from the workspace... + commandContext.deleteTopic(topic); + }, this); } + const rels = commandContext.findRelationships(this._relIds); + if (rels.length > 0) { + _.each(rels, function (rel) { + this._deletedRelModel.push(rel.getModel().clone()); + commandContext.deleteRelationship(rel); + }, this); + } + }, + + /** + * Overrides abstract parent method + * @see {@link mindplot.Command.undoExecute} + */ + undoExecute(commandContext) { + // Add all the topics ... + _.each(this._deletedTopicModels, (model) => { + commandContext.createTopic(model); + }, this); + + // Do they need to be connected ? + _.each(this._deletedTopicModels, function (topicModel, index) { + const topics = commandContext.findTopics(topicModel.getId()); + + const parentId = this._parentTopicIds[index]; + if (parentId) { + const parentTopics = commandContext.findTopics(parentId); + commandContext.connect(topics[0], parentTopics[0]); + } + }, this); + + // Add rebuild relationships ... + _.each(this._deletedRelModel, (model) => { + commandContext.addRelationship(model); + }); + + // Finally display the topics ... + _.each(this._deletedTopicModels, (topicModel) => { + const topics = commandContext.findTopics(topicModel.getId()); + topics[0].setBranchVisibility(true); + }, this); + + // Focus on last recovered topic .. + if (this._deletedTopicModels.length > 0) { + const firstTopic = this._deletedTopicModels[0]; + const topic = commandContext.findTopics(firstTopic.getId())[0]; + topic.setOnFocus(true); + } + + this._deletedTopicModels = []; + this._parentTopicIds = []; + this._deletedRelModel = []; + }, + + _filterChildren(topicIds, commandContext) { + const topics = commandContext.findTopics(topicIds); + + const result = []; + _.each(topics, (topic) => { + let parent = topic.getParent(); + let found = false; + while (parent != null && !found) { + found = topicIds.contains(parent.getId()); + if (found) { + break; + } + parent = parent.getParent(); + } + + if (!found) { + result.push(topic); + } + }); + + return result; + }, + + _collectInDepthRelationships(topic) { + let result = []; + result.append(topic.getRelationships()); + + const children = topic.getChildren(); + const rels = children.map(function (topic) { + return this._collectInDepthRelationships(topic); + }, this); + result.append(rels.flatten()); + + if (result.length > 0) { + // Filter for unique ... + result = result.sort((a, b) => a.getModel().getId() - b.getModel().getId()); + const ret = [result[0]]; + for (let i = 1; i < result.length; i++) { // start loop at 1 as element 0 can never be a duplicate + if (result[i - 1] !== result[i]) { + ret.push(result[i]); + } + } + result = ret; + } + return result; + }, + }); export default DeleteCommand; diff --git a/packages/mindplot/lib/components/commands/DragTopicCommand.js b/packages/mindplot/lib/components/commands/DragTopicCommand.js index 983f7b22..b0c5135f 100644 --- a/packages/mindplot/lib/components/commands/DragTopicCommand.js +++ b/packages/mindplot/lib/components/commands/DragTopicCommand.js @@ -15,11 +15,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const Command = require('../Command').default +const Command = require('../Command').default; const DragTopicCommand = new Class(/** @lends DragTopicCommand */{ - Extends:Command, - /** + Extends: Command, + /** * @classdesc This command class handles do/undo of dragging a topic to a new position. * @constructs * @param {String} topicId id of the topic to drag @@ -28,76 +28,72 @@ const DragTopicCommand = new Class(/** @lends DragTopicCommand */{ * @param {mindplot.Topic} parentTopic the topic to be made the dragged topic's new parent * @extends mindplot.Command */ - initialize:function (topicId, position, order, parentTopic) { - $assert(topicId, "topicId must be defined"); + initialize(topicId, position, order, parentTopic) { + $assert(topicId, 'topicId must be defined'); - this._topicsId = topicId; - if ($defined(parentTopic)) - this._parentId = parentTopic.getId(); + this._topicsId = topicId; + if ($defined(parentTopic)) this._parentId = parentTopic.getId(); - this.parent(); - this._position = position; - this._order = order; - }, + this.parent(); + this._position = position; + this._order = order; + }, - /** - * Overrides abstract parent method - */ - execute:function (commandContext) { - - var topic = commandContext.findTopics(this._topicsId)[0]; - topic.setVisibility(false); - - // Save old position ... - var origParentTopic = topic.getOutgoingConnectedTopic(); - - // In this case, topics are positioned using order ... - var origOrder = topic.getOrder(); - var origPosition = topic.getPosition(); - - // Disconnect topic .. - if ($defined(origParentTopic) && origParentTopic != this._parentId) { - commandContext.disconnect(topic); - } - - // Set topic order ... - if (this._order != null) { - topic.setOrder(this._order); - } else if (this._position != null) { - commandContext.moveTopic(topic, this._position); - } else { - $assert("Illegal command state exception."); - } - - // Finally, connect topic ... - if (origParentTopic != this._parentId) { - - if ($defined(this._parentId)) { - var parentTopic = commandContext.findTopics(this._parentId)[0]; - commandContext.connect(topic, parentTopic); - } - - // Backup old parent id ... - this._parentId = null; - if ($defined(origParentTopic)) { - this._parentId = origParentTopic.getId(); - } - } - topic.setVisibility(true); - - // Store for undo ... - this._order = origOrder; - this._position = origPosition; - - }, - - /** + /** * Overrides abstract parent method - * @see {@link mindplot.Command.undoExecute} */ - undoExecute:function (commandContext) { - this.execute(commandContext); + execute(commandContext) { + const topic = commandContext.findTopics(this._topicsId)[0]; + topic.setVisibility(false); + + // Save old position ... + const origParentTopic = topic.getOutgoingConnectedTopic(); + + // In this case, topics are positioned using order ... + const origOrder = topic.getOrder(); + const origPosition = topic.getPosition(); + + // Disconnect topic .. + if ($defined(origParentTopic) && origParentTopic != this._parentId) { + commandContext.disconnect(topic); } + + // Set topic order ... + if (this._order != null) { + topic.setOrder(this._order); + } else if (this._position != null) { + commandContext.moveTopic(topic, this._position); + } else { + $assert('Illegal command state exception.'); + } + + // Finally, connect topic ... + if (origParentTopic != this._parentId) { + if ($defined(this._parentId)) { + const parentTopic = commandContext.findTopics(this._parentId)[0]; + commandContext.connect(topic, parentTopic); + } + + // Backup old parent id ... + this._parentId = null; + if ($defined(origParentTopic)) { + this._parentId = origParentTopic.getId(); + } + } + topic.setVisibility(true); + + // Store for undo ... + this._order = origOrder; + this._position = origPosition; + }, + + /** + * Overrides abstract parent method + * @see {@link mindplot.Command.undoExecute} + */ + undoExecute(commandContext) { + this.execute(commandContext); + }, }); export default DragTopicCommand; diff --git a/packages/mindplot/lib/components/commands/GenericFunctionCommand.js b/packages/mindplot/lib/components/commands/GenericFunctionCommand.js index 583a4333..731f27de 100644 --- a/packages/mindplot/lib/components/commands/GenericFunctionCommand.js +++ b/packages/mindplot/lib/components/commands/GenericFunctionCommand.js @@ -15,13 +15,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const Command = require('../Command').default +const Command = require('../Command').default; const GenericFunctionCommand = new Class(/** @lends GenericFunctionCommand */{ - Extends:Command, - /** - * @classdesc This command handles do/undo of different actions, e.g. moving topics to - * a different position, changing text or font,... (for full reference check the + Extends: Command, + /** + * @classdesc This command handles do/undo of different actions, e.g. moving topics to + * a different position, changing text or font,... (for full reference check the * StandaloneActionDispatcher i.e. the ActionDispatcher subclass in use) * @constructs * @param {Function} commandFunc the function the command shall execute @@ -30,70 +30,66 @@ const GenericFunctionCommand = new Class(/** @lends GenericFunctionCommand */{ * e.g. color, font family or text * @extends mindplot.Command */ - initialize:function (commandFunc, topicsIds, value) { - $assert(commandFunc, "commandFunc must be defined"); - $assert($defined(topicsIds), "topicsIds must be defined"); + initialize(commandFunc, topicsIds, value) { + $assert(commandFunc, 'commandFunc must be defined'); + $assert($defined(topicsIds), 'topicsIds must be defined'); - this.parent(); - this._value = value; - this._topicsId = topicsIds; - this._commandFunc = commandFunc; - this._oldValues = []; - }, + this.parent(); + this._value = value; + this._topicsId = topicsIds; + this._commandFunc = commandFunc; + this._oldValues = []; + }, - /** - * Overrides abstract parent method - */ - execute:function (commandContext) { - if (!this.applied) { - - var topics = null; - try { - topics = commandContext.findTopics(this._topicsId); - } catch (e) { - if (this._commandFunc.commandType != "changeTextToTopic") { - // Workaround: For some reason, there is a combination of events that involves - // making some modification and firing out of focus event. This is causing - // that a remove node try to be removed. In some other life, I will come with the solution. - // Almost aways occurs with IE9. I could be related with some change of order in sets o something similar. - throw e; - } - } - - if (topics != null) { - var me = this; - _.each(topics, function (topic) { - var oldValue = me._commandFunc(topic, me._value); - me._oldValues.push(oldValue); - }); - } - this.applied = true; - - } else { - throw "Command can not be applied two times in a row."; - } - - }, - - /** + /** * Overrides abstract parent method - * @see {@link mindplot.Command.undoExecute} */ - undoExecute:function (commandContext) { - if (this.applied) { - var topics = commandContext.findTopics(this._topicsId); - var me = this; - _.each(topics, function (topic, index) { - me._commandFunc(topic, me._oldValues[index]); - - }); - - this.applied = false; - this._oldValues = []; - } else { - throw "undo can not be applied."; + execute(commandContext) { + if (!this.applied) { + let topics = null; + try { + topics = commandContext.findTopics(this._topicsId); + } catch (e) { + if (this._commandFunc.commandType != 'changeTextToTopic') { + // Workaround: For some reason, there is a combination of events that involves + // making some modification and firing out of focus event. This is causing + // that a remove node try to be removed. In some other life, I will come with the solution. + // Almost aways occurs with IE9. I could be related with some change of order in sets o something similar. + throw e; } + } + + if (topics != null) { + const me = this; + _.each(topics, (topic) => { + const oldValue = me._commandFunc(topic, me._value); + me._oldValues.push(oldValue); + }); + } + this.applied = true; + } else { + throw 'Command can not be applied two times in a row.'; } + }, + + /** + * Overrides abstract parent method + * @see {@link mindplot.Command.undoExecute} + */ + undoExecute(commandContext) { + if (this.applied) { + const topics = commandContext.findTopics(this._topicsId); + const me = this; + _.each(topics, (topic, index) => { + me._commandFunc(topic, me._oldValues[index]); + }); + + this.applied = false; + this._oldValues = []; + } else { + throw 'undo can not be applied.'; + } + }, }); -export default GenericFunctionCommand +export default GenericFunctionCommand; diff --git a/packages/mindplot/lib/components/commands/MoveControlPointCommand.js b/packages/mindplot/lib/components/commands/MoveControlPointCommand.js index 5b40c80c..fdfa9e74 100644 --- a/packages/mindplot/lib/components/commands/MoveControlPointCommand.js +++ b/packages/mindplot/lib/components/commands/MoveControlPointCommand.js @@ -18,9 +18,9 @@ const Command = require('../Command').default; const MoveControlPointCommand = new Class( - /** @lends MoveControlPointCommand */ { - Extends: Command, - /** + /** @lends MoveControlPointCommand */ { + Extends: Command, + /** * @classdesc This command handles do/undo of changing the control points of a relationship * arrow. These are the two points that appear when the relationship is on focus. They * influence how the arrow is drawn (not the source or the destination topic nor the arrow @@ -31,89 +31,88 @@ const MoveControlPointCommand = new Class( * @param ctrlPointController {ControlPoint} * @param point {Number} 0 for the destination control point, 1 for the source control point */ - initialize: function (ctrlPointController, point) { - $assert(ctrlPointController, 'line can not be null'); - $assert($defined(point), 'point can not be null'); + initialize(ctrlPointController, point) { + $assert(ctrlPointController, 'line can not be null'); + $assert($defined(point), 'point can not be null'); - this.parent(); - this._ctrlPointControler = ctrlPointController; - this._line = ctrlPointController._line; - this._controlPoint = this._ctrlPointControler.getControlPoint(point).clone(); - this._oldControlPoint = this._ctrlPointControler.getOriginalCtrlPoint(point).clone(); - this._originalEndPoint = this._ctrlPointControler.getOriginalEndPoint(point).clone(); - switch (point) { - case 0: - this._wasCustom = this._line.getLine().isSrcControlPointCustom(); - this._endPoint = this._line.getLine().getFrom().clone(); - break; - case 1: - this._wasCustom = this._line.getLine().isDestControlPointCustom(); - this._endPoint = this._line.getLine().getTo().clone(); - break; - } - this._point = point; - }, + this.parent(); + this._ctrlPointControler = ctrlPointController; + this._line = ctrlPointController._line; + this._controlPoint = this._ctrlPointControler.getControlPoint(point).clone(); + this._oldControlPoint = this._ctrlPointControler.getOriginalCtrlPoint(point).clone(); + this._originalEndPoint = this._ctrlPointControler.getOriginalEndPoint(point).clone(); + switch (point) { + case 0: + this._wasCustom = this._line.getLine().isSrcControlPointCustom(); + this._endPoint = this._line.getLine().getFrom().clone(); + break; + case 1: + this._wasCustom = this._line.getLine().isDestControlPointCustom(); + this._endPoint = this._line.getLine().getTo().clone(); + break; + } + this._point = point; + }, - /** + /** * Overrides abstract parent method */ - execute: function (commandContext) { - var model = this._line.getModel(); - switch (this._point) { - case 0: - model.setSrcCtrlPoint(this._controlPoint.clone()); - this._line.setFrom(this._endPoint.x, this._endPoint.y); - this._line.setIsSrcControlPointCustom(true); - this._line.setSrcControlPoint(this._controlPoint.clone()); - break; - case 1: - model.setDestCtrlPoint(this._controlPoint.clone()); - this._wasCustom = this._line.getLine().isDestControlPointCustom(); - this._line.setTo(this._endPoint.x, this._endPoint.y); - this._line.setIsDestControlPointCustom(true); - this._line.setDestControlPoint(this._controlPoint.clone()); - break; - } - if (this._line.isOnFocus()) { - this._line._refreshShape(); - this._ctrlPointControler.setLine(this._line); - } - this._line.getLine().updateLine(this._point); - }, + execute(commandContext) { + const model = this._line.getModel(); + switch (this._point) { + case 0: + model.setSrcCtrlPoint(this._controlPoint.clone()); + this._line.setFrom(this._endPoint.x, this._endPoint.y); + this._line.setIsSrcControlPointCustom(true); + this._line.setSrcControlPoint(this._controlPoint.clone()); + break; + case 1: + model.setDestCtrlPoint(this._controlPoint.clone()); + this._wasCustom = this._line.getLine().isDestControlPointCustom(); + this._line.setTo(this._endPoint.x, this._endPoint.y); + this._line.setIsDestControlPointCustom(true); + this._line.setDestControlPoint(this._controlPoint.clone()); + break; + } + if (this._line.isOnFocus()) { + this._line._refreshShape(); + this._ctrlPointControler.setLine(this._line); + } + this._line.getLine().updateLine(this._point); + }, - /** + /** * Overrides abstract parent method * @see {@link mindplot.Command.undoExecute} */ - undoExecute: function (commandContext) { - var line = this._line; - var model = line.getModel(); - switch (this._point) { - case 0: - if ($defined(this._oldControlPoint)) { - line.setFrom(this._originalEndPoint.x, this._originalEndPoint.y); - model.setSrcCtrlPoint(this._oldControlPoint.clone()); - line.setSrcControlPoint(this._oldControlPoint.clone()); - line.setIsSrcControlPointCustom(this._wasCustom); - } - break; - case 1: - if ($defined(this._oldControlPoint)) { - line.setTo(this._originalEndPoint.x, this._originalEndPoint.y); - model.setDestCtrlPoint(this._oldControlPoint.clone()); - line.setDestControlPoint(this._oldControlPoint.clone()); - line.setIsDestControlPointCustom(this._wasCustom); - } - break; - } - this._line.getLine().updateLine(this._point); - if (this._line.isOnFocus()) { - this._ctrlPointControler.setLine(line); - line._refreshShape(); - } - }, - } + undoExecute(commandContext) { + const line = this._line; + const model = line.getModel(); + switch (this._point) { + case 0: + if ($defined(this._oldControlPoint)) { + line.setFrom(this._originalEndPoint.x, this._originalEndPoint.y); + model.setSrcCtrlPoint(this._oldControlPoint.clone()); + line.setSrcControlPoint(this._oldControlPoint.clone()); + line.setIsSrcControlPointCustom(this._wasCustom); + } + break; + case 1: + if ($defined(this._oldControlPoint)) { + line.setTo(this._originalEndPoint.x, this._originalEndPoint.y); + model.setDestCtrlPoint(this._oldControlPoint.clone()); + line.setDestControlPoint(this._oldControlPoint.clone()); + line.setIsDestControlPointCustom(this._wasCustom); + } + break; + } + this._line.getLine().updateLine(this._point); + if (this._line.isOnFocus()) { + this._ctrlPointControler.setLine(line); + line._refreshShape(); + } + }, + }, ); export default MoveControlPointCommand; - diff --git a/packages/mindplot/lib/components/commands/RemoveFeatureFromTopicCommand.js b/packages/mindplot/lib/components/commands/RemoveFeatureFromTopicCommand.js index 389906a0..cfd725d1 100644 --- a/packages/mindplot/lib/components/commands/RemoveFeatureFromTopicCommand.js +++ b/packages/mindplot/lib/components/commands/RemoveFeatureFromTopicCommand.js @@ -17,45 +17,45 @@ */ const Command = require('../Command').default; -const RemoveFeatureFromTopicCommand = new Class(/**@lends RemoveFeatureFromTopicCommand */{ - Extends:Command, - /** - * @classdesc This command handles do/undo of removing a feature from a topic, e.g. an icon or +const RemoveFeatureFromTopicCommand = new Class(/** @lends RemoveFeatureFromTopicCommand */{ + Extends: Command, + /** + * @classdesc This command handles do/undo of removing a feature from a topic, e.g. an icon or * a note. For a reference of existing features, refer to {@link mindplot.TopicFeature}. * @constructs * @param {String} topicId id of the topic to remove the feature from * @param {String} featureId id of the feature to remove * @extends mindplot.Command */ - initialize:function (topicId, featureId) { - $assert($defined(topicId), 'topicId can not be null'); - $assert(featureId, 'iconModel can not be null'); + initialize(topicId, featureId) { + $assert($defined(topicId), 'topicId can not be null'); + $assert(featureId, 'iconModel can not be null'); - this.parent(); - this._topicId = topicId; - this._featureId = featureId; - this._oldFeature = null; - }, + this.parent(); + this._topicId = topicId; + this._featureId = featureId; + this._oldFeature = null; + }, - /** - * Overrides abstract parent method - */ - execute:function (commandContext) { - var topic = commandContext.findTopics(this._topicId)[0]; - var feature = topic.findFeatureById(this._featureId); - topic.removeFeature(feature); - this._oldFeature = feature; - }, - - /** + /** * Overrides abstract parent method - * @see {@link mindplot.Command.undoExecute} */ - undoExecute:function (commandContext) { - var topic = commandContext.findTopics(this._topicId)[0]; - topic.addFeature(this._oldFeature); - this._oldFeature = null; - } + execute(commandContext) { + const topic = commandContext.findTopics(this._topicId)[0]; + const feature = topic.findFeatureById(this._featureId); + topic.removeFeature(feature); + this._oldFeature = feature; + }, + + /** + * Overrides abstract parent method + * @see {@link mindplot.Command.undoExecute} + */ + undoExecute(commandContext) { + const topic = commandContext.findTopics(this._topicId)[0]; + topic.addFeature(this._oldFeature); + this._oldFeature = null; + }, }); export default RemoveFeatureFromTopicCommand; diff --git a/packages/mindplot/lib/components/commands/index.js b/packages/mindplot/lib/components/commands/index.js index a5ae43ab..9ce3d770 100644 --- a/packages/mindplot/lib/components/commands/index.js +++ b/packages/mindplot/lib/components/commands/index.js @@ -9,13 +9,13 @@ const moveControlPointCommand = require('./MoveControlPointCommand').default; const removeFeatureFromTopicCommand = require('./RemoveFeatureFromTopicCommand').default; export const Commands = { - AddFeatureToTopicCommand: addFeatureToTopicCommand, - AddRelationshipCommand: addRelationshipCommand, - AddTopicCommand: addTopicCommand, - ChangeFeatureToTopicCommand: changeFeatureToTopicCommand, - DeleteCommand: deleteCommand, - DragTopicCommand: dragTopicCommand, - GenericFunctionCommand: genericFunctionCommand, - MoveControlPointCommand: moveControlPointCommand, - RemoveFeatureFromTopicCommand: removeFeatureFromTopicCommand, + AddFeatureToTopicCommand: addFeatureToTopicCommand, + AddRelationshipCommand: addRelationshipCommand, + AddTopicCommand: addTopicCommand, + ChangeFeatureToTopicCommand: changeFeatureToTopicCommand, + DeleteCommand: deleteCommand, + DragTopicCommand: dragTopicCommand, + GenericFunctionCommand: genericFunctionCommand, + MoveControlPointCommand: moveControlPointCommand, + RemoveFeatureFromTopicCommand: removeFeatureFromTopicCommand, }; diff --git a/packages/mindplot/lib/components/footer.js b/packages/mindplot/lib/components/footer.js index 6858d261..4ddae25c 100644 --- a/packages/mindplot/lib/components/footer.js +++ b/packages/mindplot/lib/components/footer.js @@ -1,5 +1,5 @@ try { - $(document).trigger('loadcomplete', 'mind'); + $(document).trigger('loadcomplete', 'mind'); } catch (e) { - console.error(e.stack); + console.error(e.stack); } diff --git a/packages/mindplot/lib/components/header.js b/packages/mindplot/lib/components/header.js index 62bae0fb..e7b9b5f7 100644 --- a/packages/mindplot/lib/components/header.js +++ b/packages/mindplot/lib/components/header.js @@ -16,7 +16,7 @@ * limitations under the License. */ -var mindplot = {}; +const mindplot = {}; mindplot.util = {}; mindplot.commands = {}; mindplot.layout = {}; @@ -31,5 +31,5 @@ mindplot.persistence = {}; mindplot.layout = {}; Class.Mutators.Static = function (items) { - this.extend(items); + this.extend(items); }; diff --git a/packages/mindplot/lib/components/index.js b/packages/mindplot/lib/components/index.js index 099534b8..6c12d16f 100644 --- a/packages/mindplot/lib/components/index.js +++ b/packages/mindplot/lib/components/index.js @@ -50,59 +50,59 @@ const topicStyle = require('./TopicStyle').default; const workspace = require('./Workspace').default; export const Components = { - ActionDispatcher: actionDispatcher, + ActionDispatcher: actionDispatcher, - ActionIcon: actionIcon, - CentralTopic: centralTopic, - Command: command, - ConnectionLine: connectionLine, - ControlPoint: controlPoint, - Designer: designer, + ActionIcon: actionIcon, + CentralTopic: centralTopic, + Command: command, + ConnectionLine: connectionLine, + ControlPoint: controlPoint, + Designer: designer, - DesignerActionRunner: designerActionRunner, - DesignerKeyboard: designerKeyboard, - DesignerModel: designerModal, - DesignerUndoManager: designerUndoManager, + DesignerActionRunner: designerActionRunner, + DesignerKeyboard: designerKeyboard, + DesignerModel: designerModal, + DesignerUndoManager: designerUndoManager, - DragConnector: dragConnector, - DragManager: dragManager, - DragPivot: dragPivot, - DragTopic: dragTopic, - EditorOptions: editorOptions, - EditorProperties: editorProperties, - Events: events, + DragConnector: dragConnector, + DragManager: dragManager, + DragPivot: dragPivot, + DragTopic: dragTopic, + EditorOptions: editorOptions, + EditorProperties: editorProperties, + Events: events, - footer: footer, - header: header, + footer, + header, - Icon: icon, - IconGroup: iconGroup, - ImageIcon: imageIcon, - Keyboard: keyboard, - LinkIcon: linkIcon, + Icon: icon, + IconGroup: iconGroup, + ImageIcon: imageIcon, + Keyboard: keyboard, + LinkIcon: linkIcon, - localSorageManager: localSorageManager, - MainTopic: mainTopic, + localSorageManager, + MainTopic: mainTopic, - Messages: messages, - MultilineTextEditor: multilineTextEditor, - NodeGraph: nodeGraph, - NoteIcon: noteIcon, - Options: options, + Messages: messages, + MultilineTextEditor: multilineTextEditor, + NodeGraph: nodeGraph, + NoteIcon: noteIcon, + Options: options, - PersistenceManager: persistenceManager, - Relationship: relationship, - RelationshipPivot: relationshipPivot, - RestPersistenceManager: resetPersistenceManager, - ScreenManager: screenManager, - ShrinkConnector: shrinkConnector, - StandaloneActionDispatcher: standaloneActionDispatcher, - TextEditor: textEditor, - TextEditorFactory: textEditorFactory, + PersistenceManager: persistenceManager, + Relationship: relationship, + RelationshipPivot: relationshipPivot, + RestPersistenceManager: resetPersistenceManager, + ScreenManager: screenManager, + ShrinkConnector: shrinkConnector, + StandaloneActionDispatcher: standaloneActionDispatcher, + TextEditor: textEditor, + TextEditorFactory: textEditorFactory, - Topic: topic, - TopicEventDispatcher: topicEventDispatcher, - TopicFeature: topicFeature, - TopicStyle: topicStyle, - Workspace: workspace, + Topic: topic, + TopicEventDispatcher: topicEventDispatcher, + TopicFeature: topicFeature, + TopicStyle: topicStyle, + Workspace: workspace, }; diff --git a/packages/mindplot/lib/components/layout/AbstractBasicSorter.js b/packages/mindplot/lib/components/layout/AbstractBasicSorter.js index 1f0dc6b6..0c95b6a7 100644 --- a/packages/mindplot/lib/components/layout/AbstractBasicSorter.js +++ b/packages/mindplot/lib/components/layout/AbstractBasicSorter.js @@ -22,64 +22,62 @@ const ChildrenSorterStrategy = require('./ChildrenSorterStrategy').default; * @extends mindplot.layout.ChildrenSorterStrategy */ const AbstractBasicSorter = new Class( - /** @lends AbstractBasicSorter */ { - Extends: ChildrenSorterStrategy, + /** @lends AbstractBasicSorter */ { + Extends: ChildrenSorterStrategy, - /** + /** * @param {} treeSet * @param {} node * @return the height of a node and its children if existing and not shrunken */ - computeChildrenIdByHeights: function (treeSet, node) { - var result = {}; - this._computeChildrenHeight(treeSet, node, result); - return result; - }, + computeChildrenIdByHeights(treeSet, node) { + const result = {}; + this._computeChildrenHeight(treeSet, node, result); + return result; + }, - _getVerticalPadding: function () { - return AbstractBasicSorter.INTERNODE_VERTICAL_PADDING; - }, + _getVerticalPadding() { + return AbstractBasicSorter.INTERNODE_VERTICAL_PADDING; + }, - _computeChildrenHeight: function (treeSet, node, heightCache) { - var height = node.getSize().height + this._getVerticalPadding() * 2; // 2* Top and down padding; + _computeChildrenHeight(treeSet, node, heightCache) { + const height = node.getSize().height + this._getVerticalPadding() * 2; // 2* Top and down padding; - var result; - var children = treeSet.getChildren(node); - if (children.length == 0 || node.areChildrenShrunken()) { - result = height; - } else { - var childrenHeight = 0; - _.each( - children, - function (child) { - childrenHeight += this._computeChildrenHeight(treeSet, child, heightCache); - }, - this - ); + let result; + const children = treeSet.getChildren(node); + if (children.length == 0 || node.areChildrenShrunken()) { + result = height; + } else { + let childrenHeight = 0; + _.each( + children, + function (child) { + childrenHeight += this._computeChildrenHeight(treeSet, child, heightCache); + }, + this, + ); - result = Math.max(height, childrenHeight); - } + result = Math.max(height, childrenHeight); + } - if (heightCache) { - heightCache[node.getId()] = result; - } + if (heightCache) { + heightCache[node.getId()] = result; + } - return result; - }, + return result; + }, - _getSortedChildren: function (treeSet, node) { - var result = treeSet.getChildren(node); - result.sort(function (a, b) { - return a.getOrder() - b.getOrder(); - }); - return result; - }, + _getSortedChildren(treeSet, node) { + const result = treeSet.getChildren(node); + result.sort((a, b) => a.getOrder() - b.getOrder()); + return result; + }, - _getRelativeDirection: function (reference, position) { - var offset = position.x - reference.x; - return offset >= 0 ? 1 : -1; - }, - } + _getRelativeDirection(reference, position) { + const offset = position.x - reference.x; + return offset >= 0 ? 1 : -1; + }, + }, ); /** diff --git a/packages/mindplot/lib/components/layout/BalancedSorter.js b/packages/mindplot/lib/components/layout/BalancedSorter.js index 8812a72e..0f67c9e5 100644 --- a/packages/mindplot/lib/components/layout/BalancedSorter.js +++ b/packages/mindplot/lib/components/layout/BalancedSorter.js @@ -18,15 +18,15 @@ const AbstractBasicSorter = require('./AbstractBasicSorter').default; const BalancedSorter = new Class( - /** @lends BalancedSorter */ { - Extends: AbstractBasicSorter, - /** + /** @lends BalancedSorter */ { + Extends: AbstractBasicSorter, + /** * @constructs * @extends mindplot.layout.AbstractBasicSorter */ - initialize: function () {}, + initialize() {}, - /** + /** * @param {} graph * @param {} parent * @param {} node @@ -34,294 +34,286 @@ const BalancedSorter = new Class( * @param {Boolean} free * @return an array with order and position */ - predict: function (graph, parent, node, position, free) { - // If its a free node... - if (free) { - $assert( - $defined(position), - 'position cannot be null for predict in free positioning' - ); - $assert($defined(node), 'node cannot be null for predict in free positioning'); + predict(graph, parent, node, position, free) { + // If its a free node... + if (free) { + $assert( + $defined(position), + 'position cannot be null for predict in free positioning', + ); + $assert($defined(node), 'node cannot be null for predict in free positioning'); - var rootNode = graph.getRootNode(parent); - var direction = this._getRelativeDirection( - rootNode.getPosition(), - node.getPosition() - ); + var rootNode = graph.getRootNode(parent); + var direction = this._getRelativeDirection( + rootNode.getPosition(), + node.getPosition(), + ); - var limitXPos = - parent.getPosition().x + - direction * - (parent.getSize().width / 2 + - node.getSize().width / 2 + - BalancedSorter.INTERNODE_HORIZONTAL_PADDING); + const limitXPos = parent.getPosition().x + + direction + * (parent.getSize().width / 2 + + node.getSize().width / 2 + + BalancedSorter.INTERNODE_HORIZONTAL_PADDING); - var xPos = - direction > 0 - ? position.x >= limitXPos - ? position.x - : limitXPos - : position.x <= limitXPos - ? position.x - : limitXPos; + const xPos = direction > 0 + ? position.x >= limitXPos + ? position.x + : limitXPos + : position.x <= limitXPos + ? position.x + : limitXPos; - return [0, { x: xPos, y: position.y }]; - } + return [0, { x: xPos, y: position.y }]; + } - var rootNode = graph.getRootNode(parent); + var rootNode = graph.getRootNode(parent); - // If it is a dragged node... - if (node) { - $assert($defined(position), 'position cannot be null for predict in dragging'); - var nodeDirection = this._getRelativeDirection( - rootNode.getPosition(), - node.getPosition() - ); - var positionDirection = this._getRelativeDirection( - rootNode.getPosition(), - position - ); - var siblings = graph.getSiblings(node); + // If it is a dragged node... + if (node) { + $assert($defined(position), 'position cannot be null for predict in dragging'); + const nodeDirection = this._getRelativeDirection( + rootNode.getPosition(), + node.getPosition(), + ); + const positionDirection = this._getRelativeDirection( + rootNode.getPosition(), + position, + ); + const siblings = graph.getSiblings(node); - var sameParent = parent == graph.getParent(node); - if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) { - return [node.getOrder(), node.getPosition()]; - } - } + const sameParent = parent == graph.getParent(node); + if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) { + return [node.getOrder(), node.getPosition()]; + } + } - if (!position) { - var right = this._getChildrenForOrder(parent, graph, 0); - var left = this._getChildrenForOrder(parent, graph, 1); - } - // Filter nodes on one side.. - var order = position - ? position.x > rootNode.getPosition().x - ? 0 - : 1 - : right.length - left.length > 0 - ? 1 - : 0; - var direction = order % 2 == 0 ? 1 : -1; + if (!position) { + var right = this._getChildrenForOrder(parent, graph, 0); + var left = this._getChildrenForOrder(parent, graph, 1); + } + // Filter nodes on one side.. + const order = position + ? position.x > rootNode.getPosition().x + ? 0 + : 1 + : right.length - left.length > 0 + ? 1 + : 0; + var direction = order % 2 == 0 ? 1 : -1; - // Exclude the dragged node (if set) - var children = this._getChildrenForOrder(parent, graph, order).filter(function (child) { - return child != node; - }); + // Exclude the dragged node (if set) + const children = this._getChildrenForOrder(parent, graph, order).filter((child) => child != node); - // No children? - if (children.length == 0) { - return [ - order, - { - x: - parent.getPosition().x + - direction * - (parent.getSize().width / 2 + - BalancedSorter.INTERNODE_HORIZONTAL_PADDING * 2), - y: parent.getPosition().y, - }, - ]; - } + // No children? + if (children.length == 0) { + return [ + order, + { + x: + parent.getPosition().x + + direction + * (parent.getSize().width / 2 + + BalancedSorter.INTERNODE_HORIZONTAL_PADDING * 2), + y: parent.getPosition().y, + }, + ]; + } - // Try to fit within ... - var result = null; - var last = children.getLast(); - position = position || { x: last.getPosition().x, y: last.getPosition().y + 1 }; - _.each(children, function (child, index) { - var cpos = child.getPosition(); - if (position.y > cpos.y) { - let yOffset = - child == last - ? child.getSize().height + BalancedSorter.INTERNODE_VERTICAL_PADDING * 2 - : (children[index + 1].getPosition().y - child.getPosition().y) / 2; - result = [child.getOrder() + 2, { x: cpos.x, y: cpos.y + yOffset }]; - } - }); + // Try to fit within ... + let result = null; + const last = children.getLast(); + position = position || { x: last.getPosition().x, y: last.getPosition().y + 1 }; + _.each(children, (child, index) => { + const cpos = child.getPosition(); + if (position.y > cpos.y) { + const yOffset = child == last + ? child.getSize().height + BalancedSorter.INTERNODE_VERTICAL_PADDING * 2 + : (children[index + 1].getPosition().y - child.getPosition().y) / 2; + result = [child.getOrder() + 2, { x: cpos.x, y: cpos.y + yOffset }]; + } + }); - // Position wasn't below any node, so it must be inserted above - if (!result) { - var first = children[0]; - result = [ - position.x > 0 ? 0 : 1, - { - x: first.getPosition().x, - y: - first.getPosition().y - - first.getSize().height - - BalancedSorter.INTERNODE_VERTICAL_PADDING * 2, - }, - ]; - } + // Position wasn't below any node, so it must be inserted above + if (!result) { + const first = children[0]; + result = [ + position.x > 0 ? 0 : 1, + { + x: first.getPosition().x, + y: + first.getPosition().y + - first.getSize().height + - BalancedSorter.INTERNODE_VERTICAL_PADDING * 2, + }, + ]; + } - return result; - }, + return result; + }, - /** + /** * @param {} treeSet * @param {} parent * @param {} child * @param {} order */ - insert: function (treeSet, parent, child, order) { - var children = this._getChildrenForOrder(parent, treeSet, order); + insert(treeSet, parent, child, order) { + const children = this._getChildrenForOrder(parent, treeSet, order); - // If no children, return 0 or 1 depending on the side - if (children.length == 0) { - child.setOrder(order % 2); - return; - } + // If no children, return 0 or 1 depending on the side + if (children.length == 0) { + child.setOrder(order % 2); + return; + } - // Shift all the elements by two, so side is the same. - // In case of balanced sorter, order don't need to be continuous... - var max = 0; - for (var i = 0; i < children.length; i++) { - var node = children[i]; - max = Math.max(max, node.getOrder()); - if (node.getOrder() >= order) { - max = Math.max(max, node.getOrder() + 2); - node.setOrder(node.getOrder() + 2); - } - } + // Shift all the elements by two, so side is the same. + // In case of balanced sorter, order don't need to be continuous... + let max = 0; + for (let i = 0; i < children.length; i++) { + const node = children[i]; + max = Math.max(max, node.getOrder()); + if (node.getOrder() >= order) { + max = Math.max(max, node.getOrder() + 2); + node.setOrder(node.getOrder() + 2); + } + } - var newOrder = order > max + 1 ? max + 2 : order; - child.setOrder(newOrder); - }, + const newOrder = order > max + 1 ? max + 2 : order; + child.setOrder(newOrder); + }, - /** + /** * @param {} treeSet * @param {} node */ - detach: function (treeSet, node) { - var parent = treeSet.getParent(node); - // Filter nodes on one side.. - var children = this._getChildrenForOrder(parent, treeSet, node.getOrder()); + detach(treeSet, node) { + const parent = treeSet.getParent(node); + // Filter nodes on one side.. + const children = this._getChildrenForOrder(parent, treeSet, node.getOrder()); - _.each(children, function (child, index) { - if (child.getOrder() > node.getOrder()) { - child.setOrder(child.getOrder() - 2); - } - }); - node.setOrder(node.getOrder() % 2 == 0 ? 0 : 1); - }, + _.each(children, (child, index) => { + if (child.getOrder() > node.getOrder()) { + child.setOrder(child.getOrder() - 2); + } + }); + node.setOrder(node.getOrder() % 2 == 0 ? 0 : 1); + }, - /** + /** * @param {} treeSet * @param {} node * @return offsets */ - computeOffsets: function (treeSet, node) { - $assert(treeSet, 'treeSet can no be null.'); - $assert(node, 'node can no be null.'); + computeOffsets(treeSet, node) { + $assert(treeSet, 'treeSet can no be null.'); + $assert(node, 'node can no be null.'); - var children = this._getSortedChildren(treeSet, node); + const children = this._getSortedChildren(treeSet, node); - // Compute heights ... - var heights = children - .map(function (child) { - return { - id: child.getId(), - order: child.getOrder(), - width: child.getSize().width, - height: this._computeChildrenHeight(treeSet, child), - }; - }, this) - .reverse(); + // Compute heights ... + const heights = children + .map(function (child) { + return { + id: child.getId(), + order: child.getOrder(), + width: child.getSize().width, + height: this._computeChildrenHeight(treeSet, child), + }; + }, this) + .reverse(); - // Compute the center of the branch ... - var totalPHeight = 0; - var totalNHeight = 0; + // Compute the center of the branch ... + let totalPHeight = 0; + let totalNHeight = 0; - _.each(heights, function (elem) { - if (elem.order % 2 == 0) { - totalPHeight += elem.height; - } else { - totalNHeight += elem.height; - } - }); - var psum = totalPHeight / 2; - var nsum = totalNHeight / 2; - var ysum = 0; + _.each(heights, (elem) => { + if (elem.order % 2 == 0) { + totalPHeight += elem.height; + } else { + totalNHeight += elem.height; + } + }); + let psum = totalPHeight / 2; + let nsum = totalNHeight / 2; + let ysum = 0; - // Calculate the offsets ... - var result = {}; - for (var i = 0; i < heights.length; i++) { - var direction = heights[i].order % 2 ? -1 : 1; + // Calculate the offsets ... + const result = {}; + for (let i = 0; i < heights.length; i++) { + const direction = heights[i].order % 2 ? -1 : 1; - if (direction > 0) { - psum = psum - heights[i].height; - ysum = psum; - } else { - nsum = nsum - heights[i].height; - ysum = nsum; - } + if (direction > 0) { + psum -= heights[i].height; + ysum = psum; + } else { + nsum -= heights[i].height; + ysum = nsum; + } - var yOffset = ysum + heights[i].height / 2; - var xOffset = - direction * - (node.getSize().width / 2 + - heights[i].width / 2 + - +BalancedSorter.INTERNODE_HORIZONTAL_PADDING); + const yOffset = ysum + heights[i].height / 2; + const xOffset = direction + * (node.getSize().width / 2 + + heights[i].width / 2 + + +BalancedSorter.INTERNODE_HORIZONTAL_PADDING); - $assert(!isNaN(xOffset), 'xOffset can not be null'); - $assert(!isNaN(yOffset), 'yOffset can not be null'); + $assert(!isNaN(xOffset), 'xOffset can not be null'); + $assert(!isNaN(yOffset), 'yOffset can not be null'); - result[heights[i].id] = { x: xOffset, y: yOffset }; - } - return result; - }, + result[heights[i].id] = { x: xOffset, y: yOffset }; + } + return result; + }, - /** + /** * @param {} treeSet * @param {} node * @throw will throw an error if order elements are missing */ - verify: function (treeSet, node) { - // Check that all is consistent ... - var children = this._getChildrenForOrder(node, treeSet, node.getOrder()); + verify(treeSet, node) { + // Check that all is consistent ... + const children = this._getChildrenForOrder(node, treeSet, node.getOrder()); - // All odd ordered nodes should be "continuous" by themselves - // All even numbered nodes should be "continuous" by themselves - var factor = node.getOrder() % 2 == 0 ? 2 : 1; - for (var i = 0; i < children.length; i++) { - var order = i == 0 && factor == 1 ? 1 : factor * i; - $assert( - children[i].getOrder() == order, - 'Missing order elements. Missing order: ' + - i * factor + - '. Parent:' + - node.getId() + - ',Node:' + - children[i].getId() - ); - } - }, + // All odd ordered nodes should be "continuous" by themselves + // All even numbered nodes should be "continuous" by themselves + const factor = node.getOrder() % 2 == 0 ? 2 : 1; + for (let i = 0; i < children.length; i++) { + const order = i == 0 && factor == 1 ? 1 : factor * i; + $assert( + children[i].getOrder() == order, + `Missing order elements. Missing order: ${ + i * factor + }. Parent:${ + node.getId() + },Node:${ + children[i].getId()}`, + ); + } + }, - /** + /** * @param {} treeSet * @param {} child * @return the direction of the child within the treeSet */ - getChildDirection: function (treeSet, child) { - return child.getOrder() % 2 == 0 ? 1 : -1; - }, + getChildDirection(treeSet, child) { + return child.getOrder() % 2 == 0 ? 1 : -1; + }, - /** + /** * @return {String} the print name of this class */ - toString: function () { - return 'Balanced Sorter'; - }, + toString() { + return 'Balanced Sorter'; + }, - _getChildrenForOrder: function (parent, graph, order) { - return this._getSortedChildren(graph, parent).filter(function (child) { - return child.getOrder() % 2 == order % 2; - }); - }, + _getChildrenForOrder(parent, graph, order) { + return this._getSortedChildren(graph, parent).filter((child) => child.getOrder() % 2 == order % 2); + }, - _getVerticalPadding: function () { - return BalancedSorter.INTERNODE_VERTICAL_PADDING; - }, - } + _getVerticalPadding() { + return BalancedSorter.INTERNODE_VERTICAL_PADDING; + }, + }, ); /** diff --git a/packages/mindplot/lib/components/layout/ChangeEvent.js b/packages/mindplot/lib/components/layout/ChangeEvent.js index 6e05e369..5f55ee10 100644 --- a/packages/mindplot/lib/components/layout/ChangeEvent.js +++ b/packages/mindplot/lib/components/layout/ChangeEvent.js @@ -17,54 +17,54 @@ */ const ChangeEvent = new Class(/** @lends ChangeEvent */{ - /** + /** * @constructs * @param {} id * @throws will throw an error if the given id is not/cannot be converted to a numerical value */ - initialize:function(id) { - $assert(!isNaN(id), "id can not be null"); - this._id = id; - this._position = null; - this._order = null; - }, + initialize(id) { + $assert(!isNaN(id), 'id can not be null'); + this._id = id; + this._position = null; + this._order = null; + }, - /** @return id */ - getId:function() { - return this._id; - }, + /** @return id */ + getId() { + return this._id; + }, - /** @return order */ - getOrder: function() { - return this._order; - }, + /** @return order */ + getOrder() { + return this._order; + }, - /** @return position */ - getPosition: function() { - return this._position; - }, + /** @return position */ + getPosition() { + return this._position; + }, - /** - * @param {} value the order to set + /** + * @param {} value the order to set * @throws will throw an error if the given parameter is not/cannot be converted to a numerical * value */ - setOrder: function(value) { - $assert(!isNaN(value), "value can not be null"); - this._order = value; - }, + setOrder(value) { + $assert(!isNaN(value), 'value can not be null'); + this._order = value; + }, - /** @param {} value - * @throws will throw an error if the value is null or undefined*/ - setPosition: function(value) { - $assert(value, "value can not be null"); - this._position = value; - }, + /** @param {} value + * @throws will throw an error if the value is null or undefined */ + setPosition(value) { + $assert(value, 'value can not be null'); + this._position = value; + }, - /** @return {String} order and position */ - toString: function() { - return "[order:" + this.getOrder() + ", position: {" + this.getPosition().x + "," + this.getPosition().y + "}]"; - } + /** @return {String} order and position */ + toString() { + return `[order:${this.getOrder()}, position: {${this.getPosition().x},${this.getPosition().y}}]`; + }, }); export default ChangeEvent; diff --git a/packages/mindplot/lib/components/layout/ChildrenSorterStrategy.js b/packages/mindplot/lib/components/layout/ChildrenSorterStrategy.js index 09cd38a8..10c16dcd 100644 --- a/packages/mindplot/lib/components/layout/ChildrenSorterStrategy.js +++ b/packages/mindplot/lib/components/layout/ChildrenSorterStrategy.js @@ -17,53 +17,53 @@ */ const ChildrenSorterStrategy = new Class(/** @lends ChildrenSorterStrategy */{ - /** + /** * @constructs */ - initialize:function() { + initialize() { - }, + }, - /** @abstract */ - computeChildrenIdByHeights: function(treeSet, node) { - throw "Method must be implemented"; - }, + /** @abstract */ + computeChildrenIdByHeights(treeSet, node) { + throw 'Method must be implemented'; + }, - /** @abstract */ - computeOffsets:function(treeSet, node) { - throw "Method must be implemented"; - }, + /** @abstract */ + computeOffsets(treeSet, node) { + throw 'Method must be implemented'; + }, - /** @abstract */ - insert: function(treeSet, parent, child, order) { - throw "Method must be implemented"; - }, + /** @abstract */ + insert(treeSet, parent, child, order) { + throw 'Method must be implemented'; + }, - /** @abstract */ - detach:function(treeSet, node) { - throw "Method must be implemented"; - }, + /** @abstract */ + detach(treeSet, node) { + throw 'Method must be implemented'; + }, - /** @abstract */ - predict:function(treeSet, parent, node, position, free) { - throw "Method must be implemented"; - }, + /** @abstract */ + predict(treeSet, parent, node, position, free) { + throw 'Method must be implemented'; + }, - /** @abstract */ - verify:function(treeSet, node) { - throw "Method must be implemented"; - }, + /** @abstract */ + verify(treeSet, node) { + throw 'Method must be implemented'; + }, - /** @abstract */ - getChildDirection: function(treeSet, node) { - throw "Method must be implemented"; - }, + /** @abstract */ + getChildDirection(treeSet, node) { + throw 'Method must be implemented'; + }, - /** @abstract */ - toString:function() { - throw "Method must be implemented: print name"; - } + /** @abstract */ + toString() { + throw 'Method must be implemented: print name'; + }, }); -export default ChildrenSorterStrategy +export default ChildrenSorterStrategy; diff --git a/packages/mindplot/lib/components/layout/EventBus.js b/packages/mindplot/lib/components/layout/EventBus.js index f6eaf304..d4e473d1 100644 --- a/packages/mindplot/lib/components/layout/EventBus.js +++ b/packages/mindplot/lib/components/layout/EventBus.js @@ -18,13 +18,13 @@ const Events = require('../Events').default; const EventBus = new Class(/** @lends EventBus */{ - Implements: Events, - /** + Implements: Events, + /** * @constructs * @implements mindplot.Events */ - initialize: function() { - } + initialize() { + }, }); /** @@ -32,14 +32,14 @@ const EventBus = new Class(/** @lends EventBus */{ * @enum {String} */ EventBus.events = { - NodeResizeEvent:'NodeResizeEvent', - NodeMoveEvent:'NodeMoveEvent', - NodeShrinkEvent:'NodeShrinkEvent', - NodeConnectEvent:'NodeConnectEvent', - NodeDisconnectEvent:'NodeDisconnectEvent', - NodeAdded:'NodeAdded', - NodeRemoved:'NodeRemoved', - DoLayout:'DoLayout' + NodeResizeEvent: 'NodeResizeEvent', + NodeMoveEvent: 'NodeMoveEvent', + NodeShrinkEvent: 'NodeShrinkEvent', + NodeConnectEvent: 'NodeConnectEvent', + NodeDisconnectEvent: 'NodeDisconnectEvent', + NodeAdded: 'NodeAdded', + NodeRemoved: 'NodeRemoved', + DoLayout: 'DoLayout', }; /** instance */ diff --git a/packages/mindplot/lib/components/layout/EventBusDispatcher.js b/packages/mindplot/lib/components/layout/EventBusDispatcher.js index 4a63a604..b2e9cb15 100644 --- a/packages/mindplot/lib/components/layout/EventBusDispatcher.js +++ b/packages/mindplot/lib/components/layout/EventBusDispatcher.js @@ -15,85 +15,84 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const EventBus = require('./EventBus').default +const EventBus = require('./EventBus').default; const EventBusDispatcher = new Class(/** @lends EventBusDispatcher */{ - /** + /** * @constructs */ - initialize:function() { - this.registerBusEvents(); - }, + initialize() { + this.registerBusEvents(); + }, - /** + /** * @param {mindplot.layout.LayoutManager} layoutManager */ - setLayoutManager : function(layoutManager) { - this._layoutManager = layoutManager; - }, + setLayoutManager(layoutManager) { + this._layoutManager = layoutManager; + }, - /** + /** * register bus events */ - registerBusEvents:function () { - EventBus.instance.addEvent(EventBus.events.NodeAdded, this._nodeAdded.bind(this)); - EventBus.instance.addEvent(EventBus.events.NodeRemoved, this._nodeRemoved.bind(this)); - EventBus.instance.addEvent(EventBus.events.NodeResizeEvent, this._nodeResizeEvent.bind(this)); - EventBus.instance.addEvent(EventBus.events.NodeMoveEvent, this._nodeMoveEvent.bind(this)); - EventBus.instance.addEvent(EventBus.events.NodeDisconnectEvent, this._nodeDisconnectEvent.bind(this)); - EventBus.instance.addEvent(EventBus.events.NodeConnectEvent, this._nodeConnectEvent.bind(this)); - EventBus.instance.addEvent(EventBus.events.NodeShrinkEvent, this._nodeShrinkEvent.bind(this)); - EventBus.instance.addEvent(EventBus.events.DoLayout, this._doLayout.bind(this)); - }, + registerBusEvents() { + EventBus.instance.addEvent(EventBus.events.NodeAdded, this._nodeAdded.bind(this)); + EventBus.instance.addEvent(EventBus.events.NodeRemoved, this._nodeRemoved.bind(this)); + EventBus.instance.addEvent(EventBus.events.NodeResizeEvent, this._nodeResizeEvent.bind(this)); + EventBus.instance.addEvent(EventBus.events.NodeMoveEvent, this._nodeMoveEvent.bind(this)); + EventBus.instance.addEvent(EventBus.events.NodeDisconnectEvent, this._nodeDisconnectEvent.bind(this)); + EventBus.instance.addEvent(EventBus.events.NodeConnectEvent, this._nodeConnectEvent.bind(this)); + EventBus.instance.addEvent(EventBus.events.NodeShrinkEvent, this._nodeShrinkEvent.bind(this)); + EventBus.instance.addEvent(EventBus.events.DoLayout, this._doLayout.bind(this)); + }, - _nodeResizeEvent: function(args) { - this._layoutManager.updateNodeSize(args.node.getId(), args.size); - }, + _nodeResizeEvent(args) { + this._layoutManager.updateNodeSize(args.node.getId(), args.size); + }, - _nodeMoveEvent: function(args) { - this._layoutManager.moveNode(args.node.getId(), args.position); - }, + _nodeMoveEvent(args) { + this._layoutManager.moveNode(args.node.getId(), args.position); + }, - _nodeDisconnectEvent: function(node) { - this._layoutManager.disconnectNode(node.getId()); - }, + _nodeDisconnectEvent(node) { + this._layoutManager.disconnectNode(node.getId()); + }, - _nodeConnectEvent: function(args) { - this._layoutManager.connectNode(args.parentNode.getId(), args.childNode.getId(), args.childNode.getOrder()); + _nodeConnectEvent(args) { + this._layoutManager.connectNode(args.parentNode.getId(), args.childNode.getId(), args.childNode.getOrder()); + }, - }, + _nodeShrinkEvent(node) { + this._layoutManager.updateShrinkState(node.getId(), node.areChildrenShrunken()); + }, - _nodeShrinkEvent: function(node) { - this._layoutManager.updateShrinkState(node.getId(), node.areChildrenShrunken()); - }, - - _nodeAdded: function(node) { - // Central topic must not be added twice ... - if (node.getId() != 0) { - this._layoutManager.addNode(node.getId(), {width:10,height:10}, node.getPosition()); - this._layoutManager.updateShrinkState(node.getId(), node.areChildrenShrunken()); - } - }, - - _nodeRemoved: function(node) { - this._layoutManager.removeNode(node.getId()); - }, - - _doLayout: function() { -// (function() { - this._layoutManager.layout(true); -// console.log("---------"); -// this._layoutManager.dump(); -// console.log("---------"); -// console.log("---------"); -// }).delay(0, this); - }, - - /** @return layout manager */ - getLayoutManager: function() { - return this._layoutManager; + _nodeAdded(node) { + // Central topic must not be added twice ... + if (node.getId() != 0) { + this._layoutManager.addNode(node.getId(), { width: 10, height: 10 }, node.getPosition()); + this._layoutManager.updateShrinkState(node.getId(), node.areChildrenShrunken()); } + }, + + _nodeRemoved(node) { + this._layoutManager.removeNode(node.getId()); + }, + + _doLayout() { + // (function() { + this._layoutManager.layout(true); + // console.log("---------"); + // this._layoutManager.dump(); + // console.log("---------"); + // console.log("---------"); + // }).delay(0, this); + }, + + /** @return layout manager */ + getLayoutManager() { + return this._layoutManager; + }, }); -export default EventBusDispatcher +export default EventBusDispatcher; diff --git a/packages/mindplot/lib/components/layout/GridSorter.js b/packages/mindplot/lib/components/layout/GridSorter.js index 3e061c57..c3f6bd86 100644 --- a/packages/mindplot/lib/components/layout/GridSorter.js +++ b/packages/mindplot/lib/components/layout/GridSorter.js @@ -15,66 +15,63 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const AbstractBasicSorter = require('./AbstractBasicSorter').default +const AbstractBasicSorter = require('./AbstractBasicSorter').default; /** * @class * @extends mindplot.layout.AbstractBasicSorter */ const GridSorter = new Class(/** @lends GridSorter */{ - Extends: AbstractBasicSorter, + Extends: AbstractBasicSorter, - /** + /** * @param {} treeSet * @param {} node * @return offsets */ - computeOffsets: function(treeSet, node) { - $assert(treeSet, "treeSet can no be null."); - $assert(node, "node can no be null."); - $assert("order can no be null."); + computeOffsets(treeSet, node) { + $assert(treeSet, 'treeSet can no be null.'); + $assert(node, 'node can no be null.'); + $assert('order can no be null.'); - var children = this._getSortedChildren(treeSet, node); + const children = this._getSortedChildren(treeSet, node); - // Compute heights ... - var me = this; - var heights = children.map(function(child) { - return { - id: child.getId(), - height: me._computeChildrenHeight(treeSet, child) - }; - }); + // Compute heights ... + const me = this; + const heights = children.map((child) => ({ + id: child.getId(), + height: me._computeChildrenHeight(treeSet, child), + })); - // Calculate the offsets ... - var result = {}; - for (var i = 0; i < heights.length; i++) { - var even = i%2 == 0 ? 1 : -1; + // Calculate the offsets ... + const result = {}; + for (let i = 0; i < heights.length; i++) { + const even = i % 2 == 0 ? 1 : -1; - var zeroHeight = i == 0 ? 0 : heights[0].height/2 * even; - var middleHeight = 0; - for (var j=i-2; j>0; j=j-2) { - middleHeight += heights[j].height * even; - } - var finalHeight = i == 0 ? 0 : heights[i].height/2 * even; + const zeroHeight = i == 0 ? 0 : heights[0].height / 2 * even; + let middleHeight = 0; + for (let j = i - 2; j > 0; j -= 2) { + middleHeight += heights[j].height * even; + } + const finalHeight = i == 0 ? 0 : heights[i].height / 2 * even; - var yOffset = zeroHeight + middleHeight +finalHeight; - var xOffset = node.getSize().width + GridSorter.GRID_HORIZONTAR_SIZE; + const yOffset = zeroHeight + middleHeight + finalHeight; + const xOffset = node.getSize().width + GridSorter.GRID_HORIZONTAR_SIZE; - $assert(!isNaN(xOffset), "xOffset can not be null"); - $assert(!isNaN(yOffset), "yOffset can not be null"); + $assert(!isNaN(xOffset), 'xOffset can not be null'); + $assert(!isNaN(yOffset), 'yOffset can not be null'); - result[heights[i].id] = {x:xOffset,y:yOffset}; + result[heights[i].id] = { x: xOffset, y: yOffset }; + } + return result; + }, - } - return result; - }, - - /** + /** * @return {String} the print name of this class */ - toString:function() { - return "Grid Sorter"; - } + toString() { + return 'Grid Sorter'; + }, }); diff --git a/packages/mindplot/lib/components/layout/LayoutManager.js b/packages/mindplot/lib/components/layout/LayoutManager.js index f160a91a..b925fa61 100644 --- a/packages/mindplot/lib/components/layout/LayoutManager.js +++ b/packages/mindplot/lib/components/layout/LayoutManager.js @@ -21,9 +21,9 @@ const OriginalLayout = require('./OriginalLayout').default; const ChangeEvent = require('./ChangeEvent').default; const LayoutManager = new Class( - /** @lends LayoutManager */ { - Extends: Events, - /** + /** @lends LayoutManager */ { + Extends: Events, + /** * @constructs * @extends mindplot.Events * @param {} rootNodeId @@ -31,57 +31,57 @@ const LayoutManager = new Class( * @throws will throw an error if the root node id is null or undefined * @throws will throw an error if the root size is null */ - initialize: function (rootNodeId, rootSize) { - $assert($defined(rootNodeId), 'rootNodeId can not be null'); - $assert(rootSize, 'rootSize can not be null'); - var position = position || { x: 0, y: 0 }; + initialize(rootNodeId, rootSize) { + $assert($defined(rootNodeId), 'rootNodeId can not be null'); + $assert(rootSize, 'rootSize can not be null'); + var position = position || { x: 0, y: 0 }; - this._treeSet = new RootedTreeSet(); - this._layout = new OriginalLayout(this._treeSet); + this._treeSet = new RootedTreeSet(); + this._layout = new OriginalLayout(this._treeSet); - var rootNode = this._layout.createNode(rootNodeId, rootSize, position, 'root'); - this._treeSet.setRoot(rootNode); - this._events = []; - }, + const rootNode = this._layout.createNode(rootNodeId, rootSize, position, 'root'); + this._treeSet.setRoot(rootNode); + this._events = []; + }, - /** + /** * @param id * @param size * @throws will throw an error if id is null or undefined */ - updateNodeSize: function (id, size) { - $assert($defined(id), 'id can not be null'); + updateNodeSize(id, size) { + $assert($defined(id), 'id can not be null'); - var node = this._treeSet.find(id); - node.setSize(size); - }, + const node = this._treeSet.find(id); + node.setSize(size); + }, - /** + /** * @param id * @param value * @throws will throw an error if id is null or undefined * @throws will throw an error if value is null or undefined * @return this */ - updateShrinkState: function (id, value) { - $assert($defined(id), 'id can not be null'); - $assert($defined(value), 'value can not be null'); + updateShrinkState(id, value) { + $assert($defined(id), 'id can not be null'); + $assert($defined(value), 'value can not be null'); - var node = this._treeSet.find(id); - node.setShrunken(value); + const node = this._treeSet.find(id); + node.setShrunken(value); - return this; - }, + return this; + }, - /** + /** * @param id * @return {@link RootedTreeSet}.find(id) */ - find: function (id) { - return this._treeSet.find(id); - }, + find(id) { + return this._treeSet.find(id); + }, - /** + /** * @param id * @param position * @throws will throw an error if id is null or undefined @@ -89,20 +89,20 @@ const LayoutManager = new Class( * @throws will throw an error if the position's x property is null or undefined * @throws will throw an error if the position's y property is null or undefined */ - moveNode: function (id, position) { - $assert($defined(id), 'id cannot be null'); - $assert($defined(position), 'position cannot be null'); - $assert($defined(position.x), 'x can not be null'); - $assert($defined(position.y), 'y can not be null'); + moveNode(id, position) { + $assert($defined(id), 'id cannot be null'); + $assert($defined(position), 'position cannot be null'); + $assert($defined(position.x), 'x can not be null'); + $assert($defined(position.y), 'y can not be null'); - var node = this._treeSet.find(id); - // @Todo: this should not be here. This is broking the isolated node support... - // node.setFree(true); - // node.setFreeDisplacement({x:position.x - node.getPosition().x, y:position.y - node.getPosition().y}); - node.setPosition(position); - }, + const node = this._treeSet.find(id); + // @Todo: this should not be here. This is broking the isolated node support... + // node.setFree(true); + // node.setFreeDisplacement({x:position.x - node.getPosition().x, y:position.y - node.getPosition().y}); + node.setPosition(position); + }, - /** + /** * @param parentId * @param childId * @param order @@ -111,65 +111,65 @@ const LayoutManager = new Class( * @throws will throw an error if order is null or undefined * @return this */ - connectNode: function (parentId, childId, order) { - $assert($defined(parentId), 'parentId cannot be null'); - $assert($defined(childId), 'childId cannot be null'); - $assert($defined(order), 'order cannot be null'); + connectNode(parentId, childId, order) { + $assert($defined(parentId), 'parentId cannot be null'); + $assert($defined(childId), 'childId cannot be null'); + $assert($defined(order), 'order cannot be null'); - this._layout.connectNode(parentId, childId, order); + this._layout.connectNode(parentId, childId, order); - return this; - }, + return this; + }, - /** + /** * @param id * @throws will throw an error if id is null or undefined * @return this */ - disconnectNode: function (id) { - $assert($defined(id), 'id can not be null'); - this._layout.disconnectNode(id); + disconnectNode(id) { + $assert($defined(id), 'id can not be null'); + this._layout.disconnectNode(id); - return this; - }, + return this; + }, - /** + /** * @param id * @param size * @param position * @throws will throw an error if id is null or undefined * @return this */ - addNode: function (id, size, position) { - $assert($defined(id), 'id can not be null'); - var result = this._layout.createNode(id, size, position, 'topic'); - this._treeSet.add(result); + addNode(id, size, position) { + $assert($defined(id), 'id can not be null'); + const result = this._layout.createNode(id, size, position, 'topic'); + this._treeSet.add(result); - return this; - }, + return this; + }, - /** + /** * removes a node and its connection to parent if existing * @param id * @throws will throw an error if id is null or undefined * @return this */ - removeNode: function (id) { - $assert($defined(id), 'id can not be null'); - var node = this._treeSet.find(id); + removeNode(id) { + $assert($defined(id), 'id can not be null'); + const node = this._treeSet.find(id); - // Is It connected ? - if (this._treeSet.getParent(node)) { - this.disconnectNode(id); - } + // Is It connected ? + if (this._treeSet.getParent(node)) { + this.disconnectNode(id); + } - // Remove the all the branch ... - this._treeSet.remove(id); + // Remove the all the branch ... + this._treeSet.remove(id); - return this; - }, + return this; + }, - /** + /** * @param {Number} parentId * @param {Number=} nodeId * @param {String=} position the position to use as mindplot.layout.Node.properties position @@ -177,109 +177,107 @@ const LayoutManager = new Class( * @param {Boolean=} free true specifies free node positioning * @throws will throw an error if parentId is null or undefined */ - predict: function (parentId, nodeId, position, free) { - $assert($defined(parentId), 'parentId can not be null'); + predict(parentId, nodeId, position, free) { + $assert($defined(parentId), 'parentId can not be null'); - var parent = this._treeSet.find(parentId); - var node = nodeId ? this._treeSet.find(nodeId) : null; - var sorter = parent.getSorter(); + const parent = this._treeSet.find(parentId); + const node = nodeId ? this._treeSet.find(nodeId) : null; + const sorter = parent.getSorter(); - var result = sorter.predict(this._treeSet, parent, node, position, free); - return { order: result[0], position: result[1] }; - }, + const result = sorter.predict(this._treeSet, parent, node, position, free); + return { order: result[0], position: result[1] }; + }, - /** + /** * logs dump to console */ - dump: function () { - console.log(this._treeSet.dump()); - }, + dump() { + console.log(this._treeSet.dump()); + }, - /** + /** * @param containerId * @param {width:Number, height:Number} size * @throws will throw an error if containerId is null or undefined * @return canvas */ - plot: function (containerId, size) { - $assert(containerId, 'containerId cannot be null'); - size = size || { width: 200, height: 200 }; - var squaresize = 10; - var canvas = Raphael(containerId, size.width, size.height); - canvas.drawGrid( - 0, - 0, - size.width, - size.height, - size.width / squaresize, - size.height / squaresize - ); - this._treeSet.plot(canvas); + plot(containerId, size) { + $assert(containerId, 'containerId cannot be null'); + size = size || { width: 200, height: 200 }; + const squaresize = 10; + const canvas = Raphael(containerId, size.width, size.height); + canvas.drawGrid( + 0, + 0, + size.width, + size.height, + size.width / squaresize, + size.height / squaresize, + ); + this._treeSet.plot(canvas); - return canvas; - }, + return canvas; + }, - /** + /** * initializes the layout to be updated * @param fireEvents * @return this */ - layout: function (fireEvents) { - // File repositioning ... - this._layout.layout(); + layout(fireEvents) { + // File repositioning ... + this._layout.layout(); - // Collect changes ... - this._collectChanges(); + // Collect changes ... + this._collectChanges(); - if ($(fireEvents).length > 0 || fireEvents) { - this._flushEvents(); + if ($(fireEvents).length > 0 || fireEvents) { + this._flushEvents(); + } + + return this; + }, + + _flushEvents() { + _.each( + this._events, + function (event) { + this.fireEvent('change', event); + }, + this, + ); + this._events = []; + }, + + _collectChanges(nodes) { + if (!nodes) nodes = this._treeSet.getTreeRoots(); + + _.each( + nodes, + function (node) { + if (node.hasOrderChanged() || node.hasPositionChanged()) { + // Find or create a event ... + const id = node.getId(); + let event = this._events.some((event) => event.id == id); + if (!event) { + event = new ChangeEvent(id); } - return this; + // Update nodes ... + event.setOrder(node.getOrder()); + event.setPosition(node.getPosition()); + + node.resetPositionState(); + node.resetOrderState(); + node.resetFreeState(); + this._events.push(event); + } + this._collectChanges(this._treeSet.getChildren(node)); }, - - _flushEvents: function () { - _.each( - this._events, - function (event) { - this.fireEvent('change', event); - }, - this - ); - this._events = []; - }, - - _collectChanges: function (nodes) { - if (!nodes) nodes = this._treeSet.getTreeRoots(); - - _.each( - nodes, - function (node) { - if (node.hasOrderChanged() || node.hasPositionChanged()) { - // Find or create a event ... - var id = node.getId(); - var event = this._events.some(function (event) { - return event.id == id; - }); - if (!event) { - event = new ChangeEvent(id); - } - - // Update nodes ... - event.setOrder(node.getOrder()); - event.setPosition(node.getPosition()); - - node.resetPositionState(); - node.resetOrderState(); - node.resetFreeState(); - this._events.push(event); - } - this._collectChanges(this._treeSet.getChildren(node)); - }, - this - ); - }, - } + this, + ); + }, + }, ); export default LayoutManager; diff --git a/packages/mindplot/lib/components/layout/Node.js b/packages/mindplot/lib/components/layout/Node.js index 50dc4562..ae40e0bc 100644 --- a/packages/mindplot/lib/components/layout/Node.js +++ b/packages/mindplot/lib/components/layout/Node.js @@ -17,8 +17,8 @@ */ const Node = new Class( - /** @lends Node */ { - /** + /** @lends Node */ { + /** * @constructs * @param id * @param size @@ -29,221 +29,220 @@ const Node = new Class( * @throws will throw an error if position is null or undefined * @throws will throw an error if sorter is null or undefined */ - initialize: function (id, size, position, sorter) { - $assert(typeof id === 'number' && isFinite(id), 'id can not be null'); - $assert(size, 'size can not be null'); - $assert(position, 'position can not be null'); - $assert(sorter, 'sorter can not be null'); + initialize(id, size, position, sorter) { + $assert(typeof id === 'number' && isFinite(id), 'id can not be null'); + $assert(size, 'size can not be null'); + $assert(position, 'position can not be null'); + $assert(sorter, 'sorter can not be null'); - this._id = id; - this._sorter = sorter; - this._properties = {}; + this._id = id; + this._sorter = sorter; + this._properties = {}; - this.setSize(size); - this.setPosition(position); - this.setShrunken(false); - }, + this.setSize(size); + this.setPosition(position); + this.setShrunken(false); + }, - /** */ - getId: function () { - return this._id; - }, + /** */ + getId() { + return this._id; + }, - /** */ - setFree: function (value) { - this._setProperty('free', value); - }, + /** */ + setFree(value) { + this._setProperty('free', value); + }, - /** */ - isFree: function () { - return this._getProperty('free'); - }, + /** */ + isFree() { + return this._getProperty('free'); + }, - /** */ - hasFreeChanged: function () { - return this._isPropertyChanged('free'); - }, + /** */ + hasFreeChanged() { + return this._isPropertyChanged('free'); + }, - /** */ - hasFreeDisplacementChanged: function () { - return this._isPropertyChanged('freeDisplacement'); - }, + /** */ + hasFreeDisplacementChanged() { + return this._isPropertyChanged('freeDisplacement'); + }, - /** */ - setShrunken: function (value) { - this._setProperty('shrink', value); - }, + /** */ + setShrunken(value) { + this._setProperty('shrink', value); + }, - /** */ - areChildrenShrunken: function () { - return this._getProperty('shrink'); - }, + /** */ + areChildrenShrunken() { + return this._getProperty('shrink'); + }, - /** */ - setOrder: function (order) { - $assert( - typeof order === 'number' && isFinite(order), - 'Order can not be null. Value:' + order - ); - this._setProperty('order', order); - }, + /** */ + setOrder(order) { + $assert( + typeof order === 'number' && isFinite(order), + `Order can not be null. Value:${order}`, + ); + this._setProperty('order', order); + }, - /** */ - resetPositionState: function () { - var prop = this._properties['position']; - if (prop) { - prop.hasChanged = false; - } - }, + /** */ + resetPositionState() { + const prop = this._properties.position; + if (prop) { + prop.hasChanged = false; + } + }, - /** */ - resetOrderState: function () { - var prop = this._properties['order']; - if (prop) { - prop.hasChanged = false; - } - }, + /** */ + resetOrderState() { + const prop = this._properties.order; + if (prop) { + prop.hasChanged = false; + } + }, - /** */ - resetFreeState: function () { - var prop = this._properties['freeDisplacement']; - if (prop) { - prop.hasChanged = false; - } - }, + /** */ + resetFreeState() { + const prop = this._properties.freeDisplacement; + if (prop) { + prop.hasChanged = false; + } + }, - /** */ - getOrder: function () { - return this._getProperty('order'); - }, + /** */ + getOrder() { + return this._getProperty('order'); + }, - /** */ - hasOrderChanged: function () { - return this._isPropertyChanged('order'); - }, + /** */ + hasOrderChanged() { + return this._isPropertyChanged('order'); + }, - /** */ - hasPositionChanged: function () { - return this._isPropertyChanged('position'); - }, + /** */ + hasPositionChanged() { + return this._isPropertyChanged('position'); + }, - /** */ - hasSizeChanged: function () { - return this._isPropertyChanged('size'); - }, + /** */ + hasSizeChanged() { + return this._isPropertyChanged('size'); + }, - /** */ - getPosition: function () { - return this._getProperty('position'); - }, + /** */ + getPosition() { + return this._getProperty('position'); + }, - /** */ - setSize: function (size) { - $assert($defined(size), 'Size can not be null'); - this._setProperty('size', Object.clone(size)); - }, + /** */ + setSize(size) { + $assert($defined(size), 'Size can not be null'); + this._setProperty('size', Object.clone(size)); + }, - /** */ - getSize: function () { - return this._getProperty('size'); - }, + /** */ + getSize() { + return this._getProperty('size'); + }, - /** */ - setFreeDisplacement: function (displacement) { - $assert($defined(displacement), 'Position can not be null'); - $assert($defined(displacement.x), 'x can not be null'); - $assert($defined(displacement.y), 'y can not be null'); - var oldDisplacement = this.getFreeDisplacement(); - var newDisplacement = { - x: oldDisplacement.x + displacement.x, - y: oldDisplacement.y + displacement.y, - }; + /** */ + setFreeDisplacement(displacement) { + $assert($defined(displacement), 'Position can not be null'); + $assert($defined(displacement.x), 'x can not be null'); + $assert($defined(displacement.y), 'y can not be null'); + const oldDisplacement = this.getFreeDisplacement(); + const newDisplacement = { + x: oldDisplacement.x + displacement.x, + y: oldDisplacement.y + displacement.y, + }; - this._setProperty('freeDisplacement', Object.clone(newDisplacement)); - }, + this._setProperty('freeDisplacement', Object.clone(newDisplacement)); + }, - /** */ - resetFreeDisplacement: function () { - this._setProperty('freeDisplacement', { x: 0, y: 0 }); - }, + /** */ + resetFreeDisplacement() { + this._setProperty('freeDisplacement', { x: 0, y: 0 }); + }, - /** */ - getFreeDisplacement: function () { - var freeDisplacement = this._getProperty('freeDisplacement'); - return freeDisplacement || { x: 0, y: 0 }; - }, + /** */ + getFreeDisplacement() { + const freeDisplacement = this._getProperty('freeDisplacement'); + return freeDisplacement || { x: 0, y: 0 }; + }, - /** */ - setPosition: function (position) { - $assert($defined(position), 'Position can not be null'); - $assert($defined(position.x), 'x can not be null'); - $assert($defined(position.y), 'y can not be null'); + /** */ + setPosition(position) { + $assert($defined(position), 'Position can not be null'); + $assert($defined(position.x), 'x can not be null'); + $assert($defined(position.y), 'y can not be null'); - // This is a performance improvement to avoid movements that really could be avoided. - var currentPos = this.getPosition(); - if ( - currentPos == null || - Math.abs(currentPos.x - position.x) > 2 || - Math.abs(currentPos.y - position.y) > 2 - ) - this._setProperty('position', position); - }, + // This is a performance improvement to avoid movements that really could be avoided. + const currentPos = this.getPosition(); + if ( + currentPos == null + || Math.abs(currentPos.x - position.x) > 2 + || Math.abs(currentPos.y - position.y) > 2 + ) this._setProperty('position', position); + }, - _setProperty: function (key, value) { - var prop = this._properties[key]; - if (!prop) { - prop = { - hasChanged: false, - value: null, - oldValue: null, - }; - } + _setProperty(key, value) { + let prop = this._properties[key]; + if (!prop) { + prop = { + hasChanged: false, + value: null, + oldValue: null, + }; + } - // Only update if the property has changed ... - if (JSON.stringify(prop.value) != JSON.stringify(value)) { - prop.oldValue = prop.value; - prop.value = value; - prop.hasChanged = true; - } - this._properties[key] = prop; - }, + // Only update if the property has changed ... + if (JSON.stringify(prop.value) != JSON.stringify(value)) { + prop.oldValue = prop.value; + prop.value = value; + prop.hasChanged = true; + } + this._properties[key] = prop; + }, - _getProperty: function (key) { - var prop = this._properties[key]; - return $defined(prop) ? prop.value : null; - }, + _getProperty(key) { + const prop = this._properties[key]; + return $defined(prop) ? prop.value : null; + }, - _isPropertyChanged: function (key) { - var prop = this._properties[key]; - return prop ? prop.hasChanged : false; - }, + _isPropertyChanged(key) { + const prop = this._properties[key]; + return prop ? prop.hasChanged : false; + }, - /** */ - getSorter: function () { - return this._sorter; - }, + /** */ + getSorter() { + return this._sorter; + }, - /** @return {String} returns id, order, position, size and shrink information*/ - toString: function () { - return ( - '[id:' + - this.getId() + - ', order:' + - this.getOrder() + - ', position: {' + - this.getPosition().x + - ',' + - this.getPosition().y + - '}, size: {' + - this.getSize().width + - ',' + - this.getSize().height + - '}, shrink:' + - this.areChildrenShrunken() + - ']' - ); - }, - } + /** @return {String} returns id, order, position, size and shrink information */ + toString() { + return ( + `[id:${ + this.getId() + }, order:${ + this.getOrder() + }, position: {${ + this.getPosition().x + },${ + this.getPosition().y + }}, size: {${ + this.getSize().width + },${ + this.getSize().height + }}, shrink:${ + this.areChildrenShrunken() + }]` + ); + }, + }, ); export default Node; diff --git a/packages/mindplot/lib/components/layout/OriginalLayout.js b/packages/mindplot/lib/components/layout/OriginalLayout.js index 3beb3b40..7a338189 100644 --- a/packages/mindplot/lib/components/layout/OriginalLayout.js +++ b/packages/mindplot/lib/components/layout/OriginalLayout.js @@ -21,267 +21,259 @@ const SymmetricSorter = require('./SymmetricSorter').default; const BalancedSorter = require('./BalancedSorter').default; const OriginalLayout = new Class( - /** @lends OriginalLayout */ { - /** + /** @lends OriginalLayout */ { + /** * @constructs * @param treeSet */ - initialize: function (treeSet) { - this._treeSet = treeSet; + initialize(treeSet) { + this._treeSet = treeSet; + }, + + /** */ + createNode(id, size, position, type) { + $assert($defined(id), 'id can not be null'); + $assert(size, 'size can not be null'); + $assert(position, 'position can not be null'); + $assert(type, 'type can not be null'); + + const strategy = type === 'root' ? OriginalLayout.BALANCED_SORTER : OriginalLayout.SYMMETRIC_SORTER; + return new Node(id, size, position, strategy); + }, + + /** */ + connectNode(parentId, childId, order) { + const parent = this._treeSet.find(parentId); + const child = this._treeSet.find(childId); + + // Insert the new node ... + const sorter = parent.getSorter(); + sorter.insert(this._treeSet, parent, child, order); + + // Connect the new node ... + this._treeSet.connect(parentId, childId); + + // Fire a basic validation ... + sorter.verify(this._treeSet, parent); + }, + + /** */ + disconnectNode(nodeId) { + const node = this._treeSet.find(nodeId); + const parent = this._treeSet.getParent(node); + $assert(parent, 'Node already disconnected'); + + // Make it fixed + node.setFree(false); + node.resetFreeDisplacement(); + + // Remove from children list. + const sorter = parent.getSorter(); + sorter.detach(this._treeSet, node); + + // Disconnect the new node ... + this._treeSet.disconnect(nodeId); + + // Fire a basic validation ... + parent.getSorter().verify(this._treeSet, parent); + }, + + /** */ + layout() { + const roots = this._treeSet.getTreeRoots(); + _.each( + roots, + function (node) { + // Calculate all node heights ... + const sorter = node.getSorter(); + + const heightById = sorter.computeChildrenIdByHeights(this._treeSet, node); + + this._layoutChildren(node, heightById); + + this._fixOverlapping(node, heightById); }, + this, + ); + }, - /** */ - createNode: function (id, size, position, type) { - $assert($defined(id), 'id can not be null'); - $assert(size, 'size can not be null'); - $assert(position, 'position can not be null'); - $assert(type, 'type can not be null'); + _layoutChildren(node, heightById) { + const nodeId = node.getId(); + const children = this._treeSet.getChildren(node); + const parent = this._treeSet.getParent(node); + const childrenOrderMoved = children.some((child) => child.hasOrderChanged()); + const childrenSizeChanged = children.some((child) => child.hasSizeChanged()); - var strategy = - type === 'root' ? OriginalLayout.BALANCED_SORTER : OriginalLayout.SYMMETRIC_SORTER; - return new Node(id, size, position, strategy); - }, + // If ether any of the nodes has been changed of position or the height of the children is not + // the same, children nodes must be repositioned .... + const newBranchHeight = heightById[nodeId]; - /** */ - connectNode: function (parentId, childId, order) { - var parent = this._treeSet.find(parentId); - var child = this._treeSet.find(childId); + const parentHeightChanged = $defined(parent) ? parent._heightChanged : false; + const heightChanged = node._branchHeight != newBranchHeight; + node._heightChanged = heightChanged || parentHeightChanged; - // Insert the new node ... - var sorter = parent.getSorter(); - sorter.insert(this._treeSet, parent, child, order); + if (childrenOrderMoved || childrenSizeChanged || heightChanged || parentHeightChanged) { + const sorter = node.getSorter(); + const offsetById = sorter.computeOffsets(this._treeSet, node); + const parentPosition = node.getPosition(); + const me = this; + _.each(children, (child) => { + const offset = offsetById[child.getId()]; - // Connect the new node ... - this._treeSet.connect(parentId, childId); + const childFreeDisplacement = child.getFreeDisplacement(); + const direction = node.getSorter().getChildDirection(me._treeSet, child); - // Fire a basic validation ... - sorter.verify(this._treeSet, parent); - }, - - /** */ - disconnectNode: function (nodeId) { - var node = this._treeSet.find(nodeId); - var parent = this._treeSet.getParent(node); - $assert(parent, 'Node already disconnected'); - - // Make it fixed - node.setFree(false); - node.resetFreeDisplacement(); - - // Remove from children list. - var sorter = parent.getSorter(); - sorter.detach(this._treeSet, node); - - // Disconnect the new node ... - this._treeSet.disconnect(nodeId); - - // Fire a basic validation ... - parent.getSorter().verify(this._treeSet, parent); - }, - - /** */ - layout: function () { - var roots = this._treeSet.getTreeRoots(); - _.each( - roots, - function (node) { - // Calculate all node heights ... - var sorter = node.getSorter(); - - var heightById = sorter.computeChildrenIdByHeights(this._treeSet, node); - - this._layoutChildren(node, heightById); - - this._fixOverlapping(node, heightById); - }, - this - ); - }, - - _layoutChildren: function (node, heightById) { - var nodeId = node.getId(); - var children = this._treeSet.getChildren(node); - var parent = this._treeSet.getParent(node); - var childrenOrderMoved = children.some(function (child) { - return child.hasOrderChanged(); - }); - var childrenSizeChanged = children.some(function (child) { - return child.hasSizeChanged(); + if ( + (direction > 0 && childFreeDisplacement.x < 0) + || (direction < 0 && childFreeDisplacement.x > 0) + ) { + child.resetFreeDisplacement(); + child.setFreeDisplacement({ + x: -childFreeDisplacement.x, + y: childFreeDisplacement.y, }); + } - // If ether any of the nodes has been changed of position or the height of the children is not - // the same, children nodes must be repositioned .... - var newBranchHeight = heightById[nodeId]; + offset.x += child.getFreeDisplacement().x; + offset.y += child.getFreeDisplacement().y; - var parentHeightChanged = $defined(parent) ? parent._heightChanged : false; - var heightChanged = node._branchHeight != newBranchHeight; - node._heightChanged = heightChanged || parentHeightChanged; + const parentX = parentPosition.x; + const parentY = parentPosition.y; - if (childrenOrderMoved || childrenSizeChanged || heightChanged || parentHeightChanged) { - var sorter = node.getSorter(); - var offsetById = sorter.computeOffsets(this._treeSet, node); - var parentPosition = node.getPosition(); - var me = this; - _.each(children, function (child) { - var offset = offsetById[child.getId()]; + const newPos = { + x: parentX + offset.x, + y: parentY + offset.y + me._calculateAlignOffset(node, child, heightById), + }; + me._treeSet.updateBranchPosition(child, newPos); + }); - var childFreeDisplacement = child.getFreeDisplacement(); - var direction = node.getSorter().getChildDirection(me._treeSet, child); + node._branchHeight = newBranchHeight; + } - if ( - (direction > 0 && childFreeDisplacement.x < 0) || - (direction < 0 && childFreeDisplacement.x > 0) - ) { - child.resetFreeDisplacement(); - child.setFreeDisplacement({ - x: -childFreeDisplacement.x, - y: childFreeDisplacement.y, - }); - } - - offset.x += child.getFreeDisplacement().x; - offset.y += child.getFreeDisplacement().y; - - var parentX = parentPosition.x; - var parentY = parentPosition.y; - - var newPos = { - x: parentX + offset.x, - y: parentY + offset.y + me._calculateAlignOffset(node, child, heightById), - }; - me._treeSet.updateBranchPosition(child, newPos); - }); - - node._branchHeight = newBranchHeight; - } - - // Continue reordering the children nodes ... - _.each( - children, - function (child) { - this._layoutChildren(child, heightById); - }, - this - ); + // Continue reordering the children nodes ... + _.each( + children, + function (child) { + this._layoutChildren(child, heightById); }, + this, + ); + }, - _calculateAlignOffset: function (node, child, heightById) { - if (child.isFree()) { - return 0; - } + _calculateAlignOffset(node, child, heightById) { + if (child.isFree()) { + return 0; + } - var offset = 0; + let offset = 0; - var nodeHeight = node.getSize().height; - var childHeight = child.getSize().height; + const nodeHeight = node.getSize().height; + const childHeight = child.getSize().height; - if ( - this._treeSet.isStartOfSubBranch(child) && - this._branchIsTaller(child, heightById) - ) { - if (this._treeSet.hasSinglePathToSingleLeaf(child)) { - offset = - heightById[child.getId()] / 2 - - (childHeight + child.getSorter()._getVerticalPadding() * 2) / 2; - } else { - offset = this._treeSet.isLeaf(child) ? 0 : -(childHeight - nodeHeight) / 2; - } - } else if (nodeHeight > childHeight) { - if (this._treeSet.getSiblings(child).length > 0) { - offset = 0; - } else { - offset = nodeHeight / 2 - childHeight / 2; - } - } else if (childHeight > nodeHeight) { - if (this._treeSet.getSiblings(child).length > 0) { - offset = 0; - } else { - offset = -(childHeight / 2 - nodeHeight / 2); - } - } + if ( + this._treeSet.isStartOfSubBranch(child) + && this._branchIsTaller(child, heightById) + ) { + if (this._treeSet.hasSinglePathToSingleLeaf(child)) { + offset = heightById[child.getId()] / 2 + - (childHeight + child.getSorter()._getVerticalPadding() * 2) / 2; + } else { + offset = this._treeSet.isLeaf(child) ? 0 : -(childHeight - nodeHeight) / 2; + } + } else if (nodeHeight > childHeight) { + if (this._treeSet.getSiblings(child).length > 0) { + offset = 0; + } else { + offset = nodeHeight / 2 - childHeight / 2; + } + } else if (childHeight > nodeHeight) { + if (this._treeSet.getSiblings(child).length > 0) { + offset = 0; + } else { + offset = -(childHeight / 2 - nodeHeight / 2); + } + } - return offset; + return offset; + }, + + _branchIsTaller(node, heightById) { + return ( + heightById[node.getId()] + > node.getSize().height + node.getSorter()._getVerticalPadding() * 2 + ); + }, + + _fixOverlapping(node, heightById) { + const children = this._treeSet.getChildren(node); + + if (node.isFree()) { + this._shiftBranches(node, heightById); + } + + _.each( + children, + function (child) { + this._fixOverlapping(child, heightById); }, + this, + ); + }, - _branchIsTaller: function (node, heightById) { - return ( - heightById[node.getId()] > - node.getSize().height + node.getSorter()._getVerticalPadding() * 2 - ); + _shiftBranches(node, heightById) { + const shiftedBranches = [node]; + + const siblingsToShift = this._treeSet.getSiblingsInVerticalDirection( + node, + node.getFreeDisplacement().y, + ); + let last = node; + _.each( + siblingsToShift, + function (sibling) { + const overlappingOccurs = shiftedBranches.some(function (shiftedBranch) { + return this._branchesOverlap(shiftedBranch, sibling, heightById); + }, this); + + if (!sibling.isFree() || overlappingOccurs) { + const sAmount = node.getFreeDisplacement().y; + this._treeSet.shiftBranchPosition(sibling, 0, sAmount); + shiftedBranches.push(sibling); + } }, + this, + ); - _fixOverlapping: function (node, heightById) { - var children = this._treeSet.getChildren(node); + const branchesToShift = this._treeSet + .getBranchesInVerticalDirection(node, node.getFreeDisplacement().y) + .filter((branch) => !shiftedBranches.contains(branch)); - if (node.isFree()) { - this._shiftBranches(node, heightById); - } - - _.each( - children, - function (child) { - this._fixOverlapping(child, heightById); - }, - this - ); + _.each( + branchesToShift, + function (branch) { + const bAmount = node.getFreeDisplacement().y; + this._treeSet.shiftBranchPosition(branch, 0, bAmount); + shiftedBranches.push(branch); + last = branch; }, + this, + ); + }, - _shiftBranches: function (node, heightById) { - var shiftedBranches = [node]; + _branchesOverlap(branchA, branchB, heightById) { + // a branch doesn't really overlap with itself + if (branchA == branchB) { + return false; + } - var siblingsToShift = this._treeSet.getSiblingsInVerticalDirection( - node, - node.getFreeDisplacement().y - ); - var last = node; - _.each( - siblingsToShift, - function (sibling) { - var overlappingOccurs = shiftedBranches.some(function (shiftedBranch) { - return this._branchesOverlap(shiftedBranch, sibling, heightById); - }, this); + const topA = branchA.getPosition().y - heightById[branchA.getId()] / 2; + const bottomA = branchA.getPosition().y + heightById[branchA.getId()] / 2; + const topB = branchB.getPosition().y - heightById[branchB.getId()] / 2; + const bottomB = branchB.getPosition().y + heightById[branchB.getId()] / 2; - if (!sibling.isFree() || overlappingOccurs) { - var sAmount = node.getFreeDisplacement().y; - this._treeSet.shiftBranchPosition(sibling, 0, sAmount); - shiftedBranches.push(sibling); - } - }, - this - ); - - var branchesToShift = this._treeSet - .getBranchesInVerticalDirection(node, node.getFreeDisplacement().y) - .filter(function (branch) { - return !shiftedBranches.contains(branch); - }); - - _.each( - branchesToShift, - function (branch) { - var bAmount = node.getFreeDisplacement().y; - this._treeSet.shiftBranchPosition(branch, 0, bAmount); - shiftedBranches.push(branch); - last = branch; - }, - this - ); - }, - - _branchesOverlap: function (branchA, branchB, heightById) { - // a branch doesn't really overlap with itself - if (branchA == branchB) { - return false; - } - - var topA = branchA.getPosition().y - heightById[branchA.getId()] / 2; - var bottomA = branchA.getPosition().y + heightById[branchA.getId()] / 2; - var topB = branchB.getPosition().y - heightById[branchB.getId()] / 2; - var bottomB = branchB.getPosition().y + heightById[branchB.getId()] / 2; - - return !(topA >= bottomB || bottomA <= topB); - }, - } + return !(topA >= bottomB || bottomA <= topB); + }, + }, ); /** diff --git a/packages/mindplot/lib/components/layout/RootedTreeSet.js b/packages/mindplot/lib/components/layout/RootedTreeSet.js index 92aaac16..b144e848 100644 --- a/packages/mindplot/lib/components/layout/RootedTreeSet.js +++ b/packages/mindplot/lib/components/layout/RootedTreeSet.js @@ -17,443 +17,437 @@ */ const RootedTreeSet = new Class( - /** @lends RootedTreeSet */ { - /** @constructs */ - initialize: function () { - this._rootNodes = []; - }, + /** @lends RootedTreeSet */ { + /** @constructs */ + initialize() { + this._rootNodes = []; + }, - /** + /** * @param root * @throws will throw an error if root is null or undefined */ - setRoot: function (root) { - $assert(root, 'root can not be null'); - this._rootNodes.push(this._decodate(root)); - }, + setRoot(root) { + $assert(root, 'root can not be null'); + this._rootNodes.push(this._decodate(root)); + }, - /** getter */ - getTreeRoots: function () { - return this._rootNodes; - }, + /** getter */ + getTreeRoots() { + return this._rootNodes; + }, - _decodate: function (node) { - node._children = []; - return node; - }, + _decodate(node) { + node._children = []; + return node; + }, - /** + /** * @param {mindplot.model.NodeModel} node * @throws will throw an error if node is null or undefined * @throws will throw an error if node with id already exists * @throws will throw an error if node has been added already */ - add: function (node) { - $assert(node, 'node can not be null'); - $assert( - !this.find(node.getId(), false), - 'node already exits with this id. Id:' + node.getId() - ); - $assert(!node._children, 'node already added'); - this._rootNodes.push(this._decodate(node)); - }, + add(node) { + $assert(node, 'node can not be null'); + $assert( + !this.find(node.getId(), false), + `node already exits with this id. Id:${node.getId()}`, + ); + $assert(!node._children, 'node already added'); + this._rootNodes.push(this._decodate(node)); + }, - /** + /** * @param nodeId * @throws will throw an error if nodeId is null or undefined */ - remove: function (nodeId) { - $assert($defined(nodeId), 'nodeId can not be null'); - var node = this.find(nodeId); - this._rootNodes.erase(node); - }, + remove(nodeId) { + $assert($defined(nodeId), 'nodeId can not be null'); + const node = this.find(nodeId); + this._rootNodes.erase(node); + }, - /** + /** * @param parentId * @param childId * @throws will throw an error if parentId is null or undefined * @throws will throw an error if childId is null or undefined * @throws will throw an error if node with id childId is already a child of parent */ - connect: function (parentId, childId) { - $assert($defined(parentId), 'parent can not be null'); - $assert($defined(childId), 'child can not be null'); + connect(parentId, childId) { + $assert($defined(parentId), 'parent can not be null'); + $assert($defined(childId), 'child can not be null'); - var parent = this.find(parentId); - var child = this.find(childId, true); - $assert( - !child._parent, - 'node already connected. Id:' + child.getId() + ',previous:' + child._parent - ); + const parent = this.find(parentId); + const child = this.find(childId, true); + $assert( + !child._parent, + `node already connected. Id:${child.getId()},previous:${child._parent}`, + ); - parent._children.push(child); - child._parent = parent; - this._rootNodes.erase(child); - }, + parent._children.push(child); + child._parent = parent; + this._rootNodes.erase(child); + }, - /** + /** * @param nodeId * @throws will throw an error if nodeId is null or undefined * @throws will throw an error if node is not connected */ - disconnect: function (nodeId) { - $assert($defined(nodeId), 'nodeId can not be null'); - var node = this.find(nodeId); - $assert(node._parent, 'Node is not connected'); + disconnect(nodeId) { + $assert($defined(nodeId), 'nodeId can not be null'); + const node = this.find(nodeId); + $assert(node._parent, 'Node is not connected'); - node._parent._children.erase(node); - this._rootNodes.push(node); - node._parent = null; - }, + node._parent._children.erase(node); + this._rootNodes.push(node); + node._parent = null; + }, - /** + /** * @param id * @param validate * @throws will throw an error if id is null or undefined * @throws will throw an error if node cannot be found * @return node */ - find: function (id, validate) { - $assert($defined(id), 'id can not be null'); + find(id, validate) { + $assert($defined(id), 'id can not be null'); - var graphs = this._rootNodes; - var result = null; - for (var i = 0; i < graphs.length; i++) { - var node = graphs[i]; - result = this._find(id, node); - if (result) { - break; - } - } - validate = !$defined(validate) ? true : validate; - $assert( - validate ? result : true, - 'node could not be found id:' + id + '\n,RootedTreeSet' + this.dump() - ); - return result; - }, + const graphs = this._rootNodes; + let result = null; + for (let i = 0; i < graphs.length; i++) { + const node = graphs[i]; + result = this._find(id, node); + if (result) { + break; + } + } + validate = !$defined(validate) ? true : validate; + $assert( + validate ? result : true, + `node could not be found id:${id}\n,RootedTreeSet${this.dump()}`, + ); + return result; + }, - _find: function (id, parent) { - if (parent.getId() == id) { - return parent; - } + _find(id, parent) { + if (parent.getId() == id) { + return parent; + } - var result = null; - var children = parent._children; - for (var i = 0; i < children.length; i++) { - var child = children[i]; - result = this._find(id, child); - if (result) break; - } + let result = null; + const children = parent._children; + for (let i = 0; i < children.length; i++) { + const child = children[i]; + result = this._find(id, child); + if (result) break; + } - return result; - }, + return result; + }, - /** + /** * @param node * @throws will throw an error if nodeId is null or undefined * @return children */ - getChildren: function (node) { - $assert(node, 'node cannot be null'); - return node._children; - }, + getChildren(node) { + $assert(node, 'node cannot be null'); + return node._children; + }, - /** + /** * @param node * @throws will throw an error if node is null or undefined * @return root node or the provided node, if it has no parent */ - getRootNode: function (node) { - $assert(node, 'node cannot be null'); - var parent = this.getParent(node); - if ($defined(parent)) { - return this.getRootNode(parent); - } + getRootNode(node) { + $assert(node, 'node cannot be null'); + const parent = this.getParent(node); + if ($defined(parent)) { + return this.getRootNode(parent); + } - return node; - }, + return node; + }, - /** + /** * @param node * @throws will throw an error if node is null or undefined - * @return {Array} ancestors*/ - getAncestors: function (node) { - $assert(node, 'node cannot be null'); - return this._getAncestors(this.getParent(node), []); - }, + * @return {Array} ancestors */ + getAncestors(node) { + $assert(node, 'node cannot be null'); + return this._getAncestors(this.getParent(node), []); + }, - _getAncestors: function (node, ancestors) { - var result = ancestors; - if (node) { - result.push(node); - this._getAncestors(this.getParent(node), result); - } - return result; - }, + _getAncestors(node, ancestors) { + const result = ancestors; + if (node) { + result.push(node); + this._getAncestors(this.getParent(node), result); + } + return result; + }, - /** + /** * @param node * @throws will throw an error if node is null or undefined * @return {Array} siblings */ - getSiblings: function (node) { - $assert(node, 'node cannot be null'); - if (!$defined(node._parent)) { - return []; - } - var siblings = node._parent._children.filter(function (child) { - return child != node; - }); - return siblings; - }, + getSiblings(node) { + $assert(node, 'node cannot be null'); + if (!$defined(node._parent)) { + return []; + } + const siblings = node._parent._children.filter((child) => child != node); + return siblings; + }, - /** + /** * @param node * @throws will throw an error if node is null or undefined * @return {Boolean} whether the node has a single path to a single leaf (no branching) */ - hasSinglePathToSingleLeaf: function (node) { - $assert(node, 'node cannot be null'); - return this._hasSinglePathToSingleLeaf(node); - }, + hasSinglePathToSingleLeaf(node) { + $assert(node, 'node cannot be null'); + return this._hasSinglePathToSingleLeaf(node); + }, - _hasSinglePathToSingleLeaf: function (node) { - var children = this.getChildren(node); + _hasSinglePathToSingleLeaf(node) { + const children = this.getChildren(node); - if (children.length == 1) { - return this._hasSinglePathToSingleLeaf(children[0]); - } + if (children.length == 1) { + return this._hasSinglePathToSingleLeaf(children[0]); + } - return children.length == 0; - }, + return children.length == 0; + }, - /** + /** * @param node - * @return {Boolean} whether the node is the start of a subbranch*/ - isStartOfSubBranch: function (node) { - return this.getSiblings(node).length > 0 && this.getChildren(node).length == 1; - }, + * @return {Boolean} whether the node is the start of a subbranch */ + isStartOfSubBranch(node) { + return this.getSiblings(node).length > 0 && this.getChildren(node).length == 1; + }, - /** + /** * @param node * @throws will throw an error if node is null or undefined * @return {Boolean} whether the node is a leaf */ - isLeaf: function (node) { - $assert(node, 'node cannot be null'); - return this.getChildren(node).length == 0; - }, + isLeaf(node) { + $assert(node, 'node cannot be null'); + return this.getChildren(node).length == 0; + }, - /** + /** * @param node * @throws will throw an error if node is null or undefined * @return parent */ - getParent: function (node) { - $assert(node, 'node cannot be null'); - return node._parent; - }, + getParent(node) { + $assert(node, 'node cannot be null'); + return node._parent; + }, - /** + /** * @return result */ - dump: function () { - var branches = this._rootNodes; - var result = ''; - for (var i = 0; i < branches.length; i++) { - var branch = branches[i]; - result += this._dump(branch, ''); - } - return result; - }, + dump() { + const branches = this._rootNodes; + let result = ''; + for (let i = 0; i < branches.length; i++) { + const branch = branches[i]; + result += this._dump(branch, ''); + } + return result; + }, - _dump: function (node, indent) { - var result = indent + node + '\n'; - var children = this.getChildren(node); - for (var i = 0; i < children.length; i++) { - var child = children[i]; - result += this._dump(child, indent + ' '); - } + _dump(node, indent) { + let result = `${indent + node}\n`; + const children = this.getChildren(node); + for (let i = 0; i < children.length; i++) { + const child = children[i]; + result += this._dump(child, `${indent} `); + } - return result; - }, + return result; + }, - /** + /** * @param canvas */ - plot: function (canvas) { - var branches = this._rootNodes; - for (var i = 0; i < branches.length; i++) { - var branch = branches[i]; - this._plot(canvas, branch); - } - }, + plot(canvas) { + const branches = this._rootNodes; + for (let i = 0; i < branches.length; i++) { + const branch = branches[i]; + this._plot(canvas, branch); + } + }, - _plot: function (canvas, node, root) { - var children = this.getChildren(node); - var cx = node.getPosition().x + canvas.width / 2 - node.getSize().width / 2; - var cy = node.getPosition().y + canvas.height / 2 - node.getSize().height / 2; - var rect = canvas.rect(cx, cy, node.getSize().width, node.getSize().height); - var order = node.getOrder() == null ? 'r' : node.getOrder(); - var text = canvas.text( - node.getPosition().x + canvas.width / 2, - node.getPosition().y + canvas.height / 2, - node.getId() + '[' + order + ']' - ); - text.attr('fill', '#FFF'); - var fillColor = this._rootNodes.contains(node) - ? '#000' - : node.isFree() - ? '#abc' - : '#c00'; - rect.attr('fill', fillColor); + _plot(canvas, node, root) { + const children = this.getChildren(node); + const cx = node.getPosition().x + canvas.width / 2 - node.getSize().width / 2; + const cy = node.getPosition().y + canvas.height / 2 - node.getSize().height / 2; + const rect = canvas.rect(cx, cy, node.getSize().width, node.getSize().height); + const order = node.getOrder() == null ? 'r' : node.getOrder(); + const text = canvas.text( + node.getPosition().x + canvas.width / 2, + node.getPosition().y + canvas.height / 2, + `${node.getId()}[${order}]`, + ); + text.attr('fill', '#FFF'); + const fillColor = this._rootNodes.contains(node) + ? '#000' + : node.isFree() + ? '#abc' + : '#c00'; + rect.attr('fill', fillColor); - var rectPosition = { - x: rect.attr('x') - canvas.width / 2 + rect.attr('width') / 2, - y: rect.attr('y') - canvas.height / 2 + rect.attr('height') / 2, - }; - var rectSize = { width: rect.attr('width'), height: rect.attr('height') }; - rect.click(function () { - console.log( - '[id:' + - node.getId() + - ', order:' + - node.getOrder() + - ', position:(' + - rectPosition.x + - ',' + - rectPosition.y + - '), size:' + - rectSize.width + - 'x' + - rectSize.height + - ', freeDisplacement:(' + - node.getFreeDisplacement().x + - ',' + - node.getFreeDisplacement().y + - ')]' - ); - }); - text.click(function () { - console.log( - '[id:' + - node.getId() + - ', order:' + - node.getOrder() + - ', position:(' + - rectPosition.x + - ',' + - rectPosition.y + - '), size:' + - rectSize.width + - 'x' + - rectSize.height + - ', freeDisplacement:(' + - node.getFreeDisplacement().x + - ',' + - node.getFreeDisplacement().y + - ')]' - ); - }); + const rectPosition = { + x: rect.attr('x') - canvas.width / 2 + rect.attr('width') / 2, + y: rect.attr('y') - canvas.height / 2 + rect.attr('height') / 2, + }; + const rectSize = { width: rect.attr('width'), height: rect.attr('height') }; + rect.click(() => { + console.log( + `[id:${ + node.getId() + }, order:${ + node.getOrder() + }, position:(${ + rectPosition.x + },${ + rectPosition.y + }), size:${ + rectSize.width + }x${ + rectSize.height + }, freeDisplacement:(${ + node.getFreeDisplacement().x + },${ + node.getFreeDisplacement().y + })]`, + ); + }); + text.click(() => { + console.log( + `[id:${ + node.getId() + }, order:${ + node.getOrder() + }, position:(${ + rectPosition.x + },${ + rectPosition.y + }), size:${ + rectSize.width + }x${ + rectSize.height + }, freeDisplacement:(${ + node.getFreeDisplacement().x + },${ + node.getFreeDisplacement().y + })]`, + ); + }); - for (var i = 0; i < children.length; i++) { - var child = children[i]; - this._plot(canvas, child); - } - }, + for (let i = 0; i < children.length; i++) { + const child = children[i]; + this._plot(canvas, child); + } + }, - /** + /** * @param node * @param position */ - updateBranchPosition: function (node, position) { - var oldPos = node.getPosition(); - node.setPosition(position); + updateBranchPosition(node, position) { + const oldPos = node.getPosition(); + node.setPosition(position); - var xOffset = oldPos.x - position.x; - var yOffset = oldPos.y - position.y; + const xOffset = oldPos.x - position.x; + const yOffset = oldPos.y - position.y; - var children = this.getChildren(node); - var me = this; - _.each(children, function (child) { - me.shiftBranchPosition(child, xOffset, yOffset); - }); - }, + const children = this.getChildren(node); + const me = this; + _.each(children, (child) => { + me.shiftBranchPosition(child, xOffset, yOffset); + }); + }, - /** + /** * @param node * @param xOffset * @param yOffset */ - shiftBranchPosition: function (node, xOffset, yOffset) { - var position = node.getPosition(); - node.setPosition({ x: position.x + xOffset, y: position.y + yOffset }); + shiftBranchPosition(node, xOffset, yOffset) { + const position = node.getPosition(); + node.setPosition({ x: position.x + xOffset, y: position.y + yOffset }); - var children = this.getChildren(node); - var me = this; - _.each(children, function (child) { - me.shiftBranchPosition(child, xOffset, yOffset); - }); - }, + const children = this.getChildren(node); + const me = this; + _.each(children, (child) => { + me.shiftBranchPosition(child, xOffset, yOffset); + }); + }, - /** + /** * @param node * @param yOffset * @return siblings in the offset (vertical) direction, i.e. with lower or higher order, respectively */ - getSiblingsInVerticalDirection: function (node, yOffset) { - // siblings with lower or higher order, depending on the direction of the offset and on the same side as their parent - var parent = this.getParent(node); - var siblings = this.getSiblings(node).filter(function (sibling) { - var sameSide = - node.getPosition().x > parent.getPosition().x - ? sibling.getPosition().x > parent.getPosition().x - : sibling.getPosition().x < parent.getPosition().x; - var orderOK = - yOffset < 0 - ? sibling.getOrder() < node.getOrder() - : sibling.getOrder() > node.getOrder(); - return orderOK && sameSide; - }); + getSiblingsInVerticalDirection(node, yOffset) { + // siblings with lower or higher order, depending on the direction of the offset and on the same side as their parent + const parent = this.getParent(node); + const siblings = this.getSiblings(node).filter((sibling) => { + const sameSide = node.getPosition().x > parent.getPosition().x + ? sibling.getPosition().x > parent.getPosition().x + : sibling.getPosition().x < parent.getPosition().x; + const orderOK = yOffset < 0 + ? sibling.getOrder() < node.getOrder() + : sibling.getOrder() > node.getOrder(); + return orderOK && sameSide; + }); - if (yOffset < 0) { - siblings.reverse(); - } + if (yOffset < 0) { + siblings.reverse(); + } - return siblings; - }, + return siblings; + }, - /** + /** * @param node * @param yOffset * @return branches of the root node on the same side as the given node's, in the given * vertical direction */ - getBranchesInVerticalDirection: function (node, yOffset) { - // direct descendants of the root that do not contain the node and are on the same side - // and on the direction of the offset - var rootNode = this.getRootNode(node); - var branches = this.getChildren(rootNode).filter(function (child) { - return this._find(node.getId(), child); - }, this); + getBranchesInVerticalDirection(node, yOffset) { + // direct descendants of the root that do not contain the node and are on the same side + // and on the direction of the offset + const rootNode = this.getRootNode(node); + const branches = this.getChildren(rootNode).filter(function (child) { + return this._find(node.getId(), child); + }, this); - var branch = branches[0]; - var rootDescendants = this.getSiblings(branch).filter(function (sibling) { - var sameSide = - node.getPosition().x > rootNode.getPosition().x - ? sibling.getPosition().x > rootNode.getPosition().x - : sibling.getPosition().x < rootNode.getPosition().x; - var sameDirection = - yOffset < 0 - ? sibling.getOrder() < branch.getOrder() - : sibling.getOrder() > branch.getOrder(); - return sameSide && sameDirection; - }, this); + const branch = branches[0]; + const rootDescendants = this.getSiblings(branch).filter((sibling) => { + const sameSide = node.getPosition().x > rootNode.getPosition().x + ? sibling.getPosition().x > rootNode.getPosition().x + : sibling.getPosition().x < rootNode.getPosition().x; + const sameDirection = yOffset < 0 + ? sibling.getOrder() < branch.getOrder() + : sibling.getOrder() > branch.getOrder(); + return sameSide && sameDirection; + }, this); - return rootDescendants; - }, - } + return rootDescendants; + }, + }, ); export default RootedTreeSet; diff --git a/packages/mindplot/lib/components/layout/SymmetricSorter.js b/packages/mindplot/lib/components/layout/SymmetricSorter.js index a2a7f26e..9bb46ba3 100644 --- a/packages/mindplot/lib/components/layout/SymmetricSorter.js +++ b/packages/mindplot/lib/components/layout/SymmetricSorter.js @@ -18,15 +18,15 @@ const AbstractBasicSorter = require('./AbstractBasicSorter').default; const SymmetricSorter = new Class( - /** @lends SymmetricSorter */ { - Extends: AbstractBasicSorter, - /** + /** @lends SymmetricSorter */ { + Extends: AbstractBasicSorter, + /** * @constructs * @extends mindplot.layout.AbstractBasicSorter */ - initialize: function () {}, + initialize() {}, - /** + /** * Predict the order and position of a dragged node. * * @param graph The tree set @@ -36,190 +36,184 @@ const SymmetricSorter = new Class( * @param free Free drag or not * @return {*} */ - predict: function (graph, parent, node, position, free) { - var self = this; - var rootNode = graph.getRootNode(parent); + predict(graph, parent, node, position, free) { + const self = this; + const rootNode = graph.getRootNode(parent); - // If its a free node... - if (free) { - $assert( - $defined(position), - 'position cannot be null for predict in free positioning' - ); - $assert($defined(node), 'node cannot be null for predict in free positioning'); + // If its a free node... + if (free) { + $assert( + $defined(position), + 'position cannot be null for predict in free positioning', + ); + $assert($defined(node), 'node cannot be null for predict in free positioning'); - var direction = this._getRelativeDirection( - rootNode.getPosition(), - parent.getPosition() - ); - var limitXPos = - parent.getPosition().x + - direction * - (parent.getSize().width / 2 + - node.getSize().width / 2 + - SymmetricSorter.INTERNODE_HORIZONTAL_PADDING); + const direction = this._getRelativeDirection( + rootNode.getPosition(), + parent.getPosition(), + ); + const limitXPos = parent.getPosition().x + + direction + * (parent.getSize().width / 2 + + node.getSize().width / 2 + + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING); - var xPos = - direction > 0 - ? position.x >= limitXPos - ? position.x - : limitXPos - : position.x <= limitXPos - ? position.x - : limitXPos; + const xPos = direction > 0 + ? position.x >= limitXPos + ? position.x + : limitXPos + : position.x <= limitXPos + ? position.x + : limitXPos; - return [0, { x: xPos, y: position.y }]; - } + return [0, { x: xPos, y: position.y }]; + } - // Its not a dragged node (it is being added) - if (!node) { - var parentDirection = self._getRelativeDirection( - rootNode.getPosition(), - parent.getPosition() - ); + // Its not a dragged node (it is being added) + if (!node) { + const parentDirection = self._getRelativeDirection( + rootNode.getPosition(), + parent.getPosition(), + ); - var position = { - x: - parent.getPosition().x + - parentDirection * - (parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING), - y: parent.getPosition().y, - }; - return [graph.getChildren(parent).length, position]; - } + var position = { + x: + parent.getPosition().x + + parentDirection + * (parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING), + y: parent.getPosition().y, + }; + return [graph.getChildren(parent).length, position]; + } - // If it is a dragged node... - $assert($defined(position), 'position cannot be null for predict in dragging'); - var nodeDirection = this._getRelativeDirection( - rootNode.getPosition(), - node.getPosition() - ); - var positionDirection = this._getRelativeDirection(rootNode.getPosition(), position); - var siblings = graph.getSiblings(node); + // If it is a dragged node... + $assert($defined(position), 'position cannot be null for predict in dragging'); + const nodeDirection = this._getRelativeDirection( + rootNode.getPosition(), + node.getPosition(), + ); + const positionDirection = this._getRelativeDirection(rootNode.getPosition(), position); + const siblings = graph.getSiblings(node); - // node has no siblings and its trying to reconnect to its own parent - var sameParent = parent == graph.getParent(node); - if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) { - return [node.getOrder(), node.getPosition()]; - } + // node has no siblings and its trying to reconnect to its own parent + const sameParent = parent == graph.getParent(node); + if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) { + return [node.getOrder(), node.getPosition()]; + } - var parentChildren = graph.getChildren(parent); + const parentChildren = graph.getChildren(parent); - if (parentChildren.length == 0) { - // Fit as a child of the parent node... - var position = { - x: - parent.getPosition().x + - positionDirection * - (parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING), - y: parent.getPosition().y, - }; - return [0, position]; - } else { - // Try to fit within ... - var result = null; - var last = parentChildren.getLast(); - for (var i = 0; i < parentChildren.length; i++) { - var parentChild = parentChildren[i]; - var nodeAfter = i + 1 == parentChild.length ? null : parentChildren[i + 1]; + if (parentChildren.length == 0) { + // Fit as a child of the parent node... + var position = { + x: + parent.getPosition().x + + positionDirection + * (parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING), + y: parent.getPosition().y, + }; + return [0, position]; + } + // Try to fit within ... + const result = null; + const last = parentChildren.getLast(); + for (let i = 0; i < parentChildren.length; i++) { + const parentChild = parentChildren[i]; + const nodeAfter = i + 1 == parentChild.length ? null : parentChildren[i + 1]; - // Fit at the bottom - if (!nodeAfter && position.y > parentChild.getPosition().y) { - var order = - graph.getParent(node) && graph.getParent(node).getId() == parent.getId() - ? last.getOrder() - : last.getOrder() + 1; - var position = { - x: parentChild.getPosition().x, - y: - parentChild.getPosition().y + - parentChild.getSize().height + - SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2, - }; - return [order, position]; - } + // Fit at the bottom + if (!nodeAfter && position.y > parentChild.getPosition().y) { + var order = graph.getParent(node) && graph.getParent(node).getId() == parent.getId() + ? last.getOrder() + : last.getOrder() + 1; + var position = { + x: parentChild.getPosition().x, + y: + parentChild.getPosition().y + + parentChild.getSize().height + + SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2, + }; + return [order, position]; + } - // Fit after this node - if ( - nodeAfter && - position.y > parentChild.getPosition().y && - position.y < nodeAfter.getPosition().y - ) { - if ( - nodeAfter.getId() == node.getId() || - parentChild.getId() == node.getId() - ) { - return [node.getOrder(), node.getPosition()]; - } else { - var order = - position.y > node.getPosition().y - ? nodeAfter.getOrder() - 1 - : parentChild.getOrder() + 1; - var position = { - x: parentChild.getPosition().x, - y: - parentChild.getPosition().y + - (nodeAfter.getPosition().y - parentChild.getPosition().y) / 2, - }; - return [order, position]; - } - } - } - } + // Fit after this node + if ( + nodeAfter + && position.y > parentChild.getPosition().y + && position.y < nodeAfter.getPosition().y + ) { + if ( + nodeAfter.getId() == node.getId() + || parentChild.getId() == node.getId() + ) { + return [node.getOrder(), node.getPosition()]; + } + var order = position.y > node.getPosition().y + ? nodeAfter.getOrder() - 1 + : parentChild.getOrder() + 1; + var position = { + x: parentChild.getPosition().x, + y: + parentChild.getPosition().y + + (nodeAfter.getPosition().y - parentChild.getPosition().y) / 2, + }; + return [order, position]; + } + } - // Position wasn't below any node, so it must be fitted above the first - var first = parentChildren[0]; - var position = { - x: first.getPosition().x, - y: - first.getPosition().y - - first.getSize().height - - SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2, - }; - return [0, position]; - }, + // Position wasn't below any node, so it must be fitted above the first + const first = parentChildren[0]; + var position = { + x: first.getPosition().x, + y: + first.getPosition().y + - first.getSize().height + - SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2, + }; + return [0, position]; + }, - /** + /** * @param treeSet * @param parent * @param child * @param order * @throws will throw an error if the order is not strictly continuous */ - insert: function (treeSet, parent, child, order) { - var children = this._getSortedChildren(treeSet, parent); - $assert( - order <= children.length, - 'Order must be continues and can not have holes. Order:' + order - ); + insert(treeSet, parent, child, order) { + const children = this._getSortedChildren(treeSet, parent); + $assert( + order <= children.length, + `Order must be continues and can not have holes. Order:${order}`, + ); - // Shift all the elements in one . - for (var i = order; i < children.length; i++) { - var node = children[i]; - node.setOrder(i + 1); - } - child.setOrder(order); - }, + // Shift all the elements in one . + for (let i = order; i < children.length; i++) { + const node = children[i]; + node.setOrder(i + 1); + } + child.setOrder(order); + }, - /** + /** * @param treeSet * @param node - * @throws will throw an error if the node is in the wrong position*/ - detach: function (treeSet, node) { - var parent = treeSet.getParent(node); - var children = this._getSortedChildren(treeSet, parent); - var order = node.getOrder(); - $assert(children[order] === node, 'Node seems not to be in the right position'); + * @throws will throw an error if the node is in the wrong position */ + detach(treeSet, node) { + const parent = treeSet.getParent(node); + const children = this._getSortedChildren(treeSet, parent); + const order = node.getOrder(); + $assert(children[order] === node, 'Node seems not to be in the right position'); - // Shift all the nodes ... - for (var i = node.getOrder() + 1; i < children.length; i++) { - var child = children[i]; - child.setOrder(child.getOrder() - 1); - } - node.setOrder(0); - }, + // Shift all the nodes ... + for (let i = node.getOrder() + 1; i < children.length; i++) { + const child = children[i]; + child.setOrder(child.getOrder() - 1); + } + node.setOrder(0); + }, - /** + /** * @param treeSet * @param node * @throws will throw an error if treeSet is null or undefined @@ -230,100 +224,99 @@ const SymmetricSorter = new Class( * value, is null or undefined * @return offsets */ - computeOffsets: function (treeSet, node) { - $assert(treeSet, 'treeSet can no be null.'); - $assert(node, 'node can no be null.'); + computeOffsets(treeSet, node) { + $assert(treeSet, 'treeSet can no be null.'); + $assert(node, 'node can no be null.'); - var children = this._getSortedChildren(treeSet, node); + const children = this._getSortedChildren(treeSet, node); - // Compute heights ... - var heights = children - .map(function (child) { - return { - id: child.getId(), - order: child.getOrder(), - position: child.getPosition(), - width: child.getSize().width, - height: this._computeChildrenHeight(treeSet, child), - }; - }, this) - .reverse(); + // Compute heights ... + const heights = children + .map(function (child) { + return { + id: child.getId(), + order: child.getOrder(), + position: child.getPosition(), + width: child.getSize().width, + height: this._computeChildrenHeight(treeSet, child), + }; + }, this) + .reverse(); - // Compute the center of the branch ... - var totalHeight = 0; - _.each(heights, function (elem) { - totalHeight += elem.height; - }); - var ysum = totalHeight / 2; + // Compute the center of the branch ... + let totalHeight = 0; + _.each(heights, (elem) => { + totalHeight += elem.height; + }); + let ysum = totalHeight / 2; - // Calculate the offsets ... - var result = {}; - for (var i = 0; i < heights.length; i++) { - ysum = ysum - heights[i].height; - var childNode = treeSet.find(heights[i].id); - var direction = this.getChildDirection(treeSet, childNode); + // Calculate the offsets ... + const result = {}; + for (let i = 0; i < heights.length; i++) { + ysum -= heights[i].height; + const childNode = treeSet.find(heights[i].id); + const direction = this.getChildDirection(treeSet, childNode); - var yOffset = ysum + heights[i].height / 2; - var xOffset = - direction * - (heights[i].width / 2 + - node.getSize().width / 2 + - SymmetricSorter.INTERNODE_HORIZONTAL_PADDING); + const yOffset = ysum + heights[i].height / 2; + const xOffset = direction + * (heights[i].width / 2 + + node.getSize().width / 2 + + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING); - $assert(!isNaN(xOffset), 'xOffset can not be null'); - $assert(!isNaN(yOffset), 'yOffset can not be null'); + $assert(!isNaN(xOffset), 'xOffset can not be null'); + $assert(!isNaN(yOffset), 'yOffset can not be null'); - result[heights[i].id] = { x: xOffset, y: yOffset }; - } - return result; - }, + result[heights[i].id] = { x: xOffset, y: yOffset }; + } + return result; + }, - /** + /** * @param treeSet * @param node * @throws will throw an error if order elements are missing */ - verify: function (treeSet, node) { - // Check that all is consistent ... - var children = this._getSortedChildren(treeSet, node); + verify(treeSet, node) { + // Check that all is consistent ... + const children = this._getSortedChildren(treeSet, node); - for (var i = 0; i < children.length; i++) { - $assert(children[i].getOrder() == i, 'missing order elements'); - } - }, + for (let i = 0; i < children.length; i++) { + $assert(children[i].getOrder() == i, 'missing order elements'); + } + }, - /** + /** * @param treeSet * @param child - * @return direction of the given child from its parent or from the root node, if isolated*/ - getChildDirection: function (treeSet, child) { - $assert(treeSet, 'treeSet can no be null.'); - $assert(treeSet.getParent(child), 'This should not happen'); + * @return direction of the given child from its parent or from the root node, if isolated */ + getChildDirection(treeSet, child) { + $assert(treeSet, 'treeSet can no be null.'); + $assert(treeSet.getParent(child), 'This should not happen'); - var result; - var rootNode = treeSet.getRootNode(child); - if (treeSet.getParent(child) == rootNode) { - // This is the case of a isolated child ... In this case, the directions is based on the root. - result = Math.sign(rootNode.getPosition().x); - } else { - // if this is not the case, honor the direction of the parent ... - var parent = treeSet.getParent(child); - var grandParent = treeSet.getParent(parent); - var sorter = grandParent.getSorter(); - result = sorter.getChildDirection(treeSet, parent); - } - return result; - }, + let result; + const rootNode = treeSet.getRootNode(child); + if (treeSet.getParent(child) == rootNode) { + // This is the case of a isolated child ... In this case, the directions is based on the root. + result = Math.sign(rootNode.getPosition().x); + } else { + // if this is not the case, honor the direction of the parent ... + const parent = treeSet.getParent(child); + const grandParent = treeSet.getParent(parent); + const sorter = grandParent.getSorter(); + result = sorter.getChildDirection(treeSet, parent); + } + return result; + }, - /** @return {String} the print name of this class */ - toString: function () { - return 'Symmetric Sorter'; - }, + /** @return {String} the print name of this class */ + toString() { + return 'Symmetric Sorter'; + }, - _getVerticalPadding: function () { - return SymmetricSorter.INTERNODE_VERTICAL_PADDING; - }, - } + _getVerticalPadding() { + return SymmetricSorter.INTERNODE_VERTICAL_PADDING; + }, + }, ); /** diff --git a/packages/mindplot/lib/components/layout/index.js b/packages/mindplot/lib/components/layout/index.js index 559fda48..c4f9dac4 100644 --- a/packages/mindplot/lib/components/layout/index.js +++ b/packages/mindplot/lib/components/layout/index.js @@ -12,16 +12,16 @@ const rootedTreeSet = require('./RootedTreeSet').default; const symmetricSorter = require('./SymmetricSorter').default; export const Layout = { - AbstractBasicSorter: abstractBasicSorter, - BalancedSorter: balancedSorter, - ChangeEvent: changeEvent, - ChildrenSorterStrategy: childrenSorterStrategy, - EventBus: eventBus, - EventBusDispatcher: eventBusDispatcher, - GridSorter: gridSorter, - LayoutManager: layoutManager, - Node: node, - OriginalLayout: originalLayout, - RootedTreeSet: rootedTreeSet, - SymmetricSorter: symmetricSorter, + AbstractBasicSorter: abstractBasicSorter, + BalancedSorter: balancedSorter, + ChangeEvent: changeEvent, + ChildrenSorterStrategy: childrenSorterStrategy, + EventBus: eventBus, + EventBusDispatcher: eventBusDispatcher, + GridSorter: gridSorter, + LayoutManager: layoutManager, + Node: node, + OriginalLayout: originalLayout, + RootedTreeSet: rootedTreeSet, + SymmetricSorter: symmetricSorter, }; diff --git a/packages/mindplot/lib/components/libraries/bootstrap/BootstrapDialog.Request.js b/packages/mindplot/lib/components/libraries/bootstrap/BootstrapDialog.Request.js index a9c7eee9..01920850 100644 --- a/packages/mindplot/lib/components/libraries/bootstrap/BootstrapDialog.Request.js +++ b/packages/mindplot/lib/components/libraries/bootstrap/BootstrapDialog.Request.js @@ -1,51 +1,50 @@ -const BootstrapDialog = require('./BootstrapDialog').default +const BootstrapDialog = require('./BootstrapDialog').default; BootstrapDialog.Request = new Class({ - Extends: BootstrapDialog, + Extends: BootstrapDialog, - initialize: function(url, title, options) { - this.parent(title, options); - this.requestOptions = {}; - this.requestOptions.cache = false; - var me = this; - this.requestOptions.fail = function(xhr) { - // Intercept form requests ... - console.log("Failure:"); - console.log(xhr); - }; + initialize(url, title, options) { + this.parent(title, options); + this.requestOptions = {}; + this.requestOptions.cache = false; + const me = this; + this.requestOptions.fail = function (xhr) { + // Intercept form requests ... + console.log('Failure:'); + console.log(xhr); + }; - this.requestOptions.success = function() { - // Intercept form requests ... - var forms = me._native.find('form'); - _.each(forms, function(form) { - $(form).on('submit', function(event) { - // Intercept form ... - me.requestOptions.url = form.action; - me.requestOptions.method = form.method ? form.method : 'post'; - $.ajax(me.requestOptions); - event.stopPropagation(); - return false; - }); - }); - }; - - this._native.find('.modal-body').load(url, function () { - me.acceptButton.unbind('click').click(function () { - submitDialogForm(); - }); - me._native.on('hidden.bs.modal', function () { - $(this).remove(); - }); - me.show(); + this.requestOptions.success = function () { + // Intercept form requests ... + const forms = me._native.find('form'); + _.each(forms, (form) => { + $(form).on('submit', (event) => { + // Intercept form ... + me.requestOptions.url = form.action; + me.requestOptions.method = form.method ? form.method : 'post'; + $.ajax(me.requestOptions); + event.stopPropagation(); + return false; }); - }, + }); + }; - onDialogShown: function() { - if (typeof(onDialogShown) == "function") { - onDialogShown(); - } + this._native.find('.modal-body').load(url, () => { + me.acceptButton.unbind('click').click(() => { + submitDialogForm(); + }); + me._native.on('hidden.bs.modal', function () { + $(this).remove(); + }); + me.show(); + }); + }, + + onDialogShown() { + if (typeof (onDialogShown) === 'function') { + onDialogShown(); } - + }, }); diff --git a/packages/mindplot/lib/components/libraries/bootstrap/BootstrapDialog.js b/packages/mindplot/lib/components/libraries/bootstrap/BootstrapDialog.js index 62d2eefc..5aa9a24a 100644 --- a/packages/mindplot/lib/components/libraries/bootstrap/BootstrapDialog.js +++ b/packages/mindplot/lib/components/libraries/bootstrap/BootstrapDialog.js @@ -1,115 +1,115 @@ const Options = require('../../Options').default; const BootstrapDialog = new Class({ - Implements: Options, + Implements: Options, - options: { - cancelButton: false, - closeButton: false, - acceptButton: true, - removeButton:false, - errorMessage: false, - onEventData:{} - }, + options: { + cancelButton: false, + closeButton: false, + acceptButton: true, + removeButton: false, + errorMessage: false, + onEventData: {}, + }, - initialize: function (title, options) { - this.setOptions(options); - this.options.onEventData.dialog = this; - this._native = $('').append(''); - var content = $(''); - var header = this._buildHeader(title); - if (header) { - content.append(header); - } - var body = $(''); - if(this.options.errorMessage){ - var error = $('
'); - error.hide(); - body.append(error); - } - content.append(body); - var footer = this._buildFooter(); - if (footer) { - content.append(footer); - } - this._native.find(".modal-dialog").append(content); - this._native.on('hidden.bs.modal', function() { - $(this).remove(); - }); - this._native.on('shown.bs.modal', this.onDialogShown); - }, - - _buildFooter: function() { - var footer = null; - if (this.options.acceptButton || this.options.removeButton || this.options.cancelButton) { - footer = $('