diff --git a/.gitignore b/.gitignore index ec9e1e33..26082af1 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,6 @@ wisemapping-frontend.code-workspace !.yarn/releases !.yarn/plugins .pnp.* + +packages/**/.yalc/ +packages/**/yalc.lock diff --git a/package.json b/package.json index 61772b1d..53d15466 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "wisemapping-front-end", "scripts": { - "bootstrap": "lerna bootstrap", + "bootstrap": "lerna run bootstrap", "build": "lerna run build", "clean": "lerna clean && rm -rf node_modules", "lint": "lerna run lint --stream", diff --git a/packages/core-js/package.json b/packages/core-js/package.json index 2c6f0389..eebdeb79 100644 --- a/packages/core-js/package.json +++ b/packages/core-js/package.json @@ -4,7 +4,7 @@ "description": "WiseMapping - Core Common Libraries", "homepage": "http://www.wisemapping.org/", "license": "MIT", - "main": "dist/core.js", + "main": "src/index.ts", "files": [ "src" ], @@ -17,6 +17,7 @@ }, "scripts": { "build": "webpack --config webpack.prod.js", - "dev": "webpack --mode development --config webpack.dev.js" + "dev": "webpack --mode development --config webpack.dev.js", + "bootstrap": "yalc publish" } } diff --git a/packages/core-js/src/index.js b/packages/core-js/src/index.js deleted file mode 100644 index b0db20c1..00000000 --- a/packages/core-js/src/index.js +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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. - */ - -/** - * Cross-browser implementation of creating an XML document object. - */ -export const createDocument = function () { - var doc = null; - if ($defined(window.ActiveXObject)) { - //http://blogs.msdn.com/b/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx - var progIDs = ['Msxml2.DOMDocument.6.0', 'Msxml2.DOMDocument.3.0']; - for (var i = 0; i < progIDs.length; i++) { - try { - doc = new ActiveXObject(progIDs[i]); - break; - } catch (ex) {} - } - } else if (window.document.implementation && window.document.implementation.createDocument) { - doc = window.document.implementation.createDocument('', '', null); - } - $assert(doc, 'Parser could not be instantiated'); - - return doc; -}; - -/* - Function: $defined - Returns true if the passed in value/object is defined, that means is not null or undefined. - - Arguments: - obj - object to inspect - */ - -export const $defined = function (obj) { - return obj != undefined; -}; - -export const $assert = function (assert, message) { - if (!$defined(assert) || !assert) { - logStackTrace(); - console.log(message); - throw new Error(message); - } -}; - -export const sign = function (value) { - return value >= 0 ? 1 : -1; -}; - -export function logStackTrace(exception) { - if (!$defined(exception)) { - try { - throw Error('Unexpected Exception'); - } catch (e) { - exception = e; - } - } - var result = ''; - if (exception.stack) { - //Firefox and Chrome... - result = exception.stack; - } else if (window.opera && exception.message) { - //Opera - result = exception.message; - } else { - //IE and Safari - result = exception.sourceURL + ': ' + exception.line + '\n\n'; - - var currentFunction = arguments.callee.caller; - while (currentFunction) { - var fn = currentFunction.toString(); - result = result + '\n' + fn; - currentFunction = currentFunction.caller; - } - } - window.errorStack = result; - return result; -} diff --git a/packages/core-js/src/index.ts b/packages/core-js/src/index.ts new file mode 100644 index 00000000..32918ef8 --- /dev/null +++ b/packages/core-js/src/index.ts @@ -0,0 +1,45 @@ +/* + * 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. + */ + +export const createDocument = (): Document => { + var doc: Document | null = null; + if (window.document.implementation?.createDocument) { + doc = window.document.implementation.createDocument('', '', null); + } + + if (!doc) { + throw new Error('Document could not be initialized'); + } + + return doc; +}; + +export const $defined = (obj: any) => { + return obj != undefined && obj != null; +}; + +export const $assert = (assert, message: string): void => { + if (!$defined(assert) || !assert) { + console.error(message); + throw new Error(message); + } +}; + +export const sign = (value: number): 1 | -1 => { + return value >= 0 ? 1 : -1; +}; diff --git a/packages/core-js/tsconfig.json b/packages/core-js/tsconfig.json new file mode 100644 index 00000000..e6134b61 --- /dev/null +++ b/packages/core-js/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "outDir": "./dist/", + "sourceMap": true, + "module": "amd", + "moduleResolution": "node", + "target": "es6", + "allowJs": true, + "strict": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "declaration": true, + "strictNullChecks": true, + + "noImplicitAny": false, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": true, + "strictFunctionTypes": true, + + "rootDirs": [ + "src", + ] + }, + "include": [ + "src/**/*", "storybook/src/stories", + ], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/packages/core-js/webpack.common.js b/packages/core-js/webpack.common.js index f92cb988..a7b59435 100644 --- a/packages/core-js/webpack.common.js +++ b/packages/core-js/webpack.common.js @@ -5,15 +5,11 @@ const common = require('../../webpack.common'); const prodConfig = { output: { path: path.resolve(__dirname, 'dist'), - filename: 'core.js', - publicPath: '', + filename: 'index.ts', library: { type: 'umd', }, - }, - target: 'web', - - + } }; module.exports = merge(common, prodConfig); diff --git a/packages/core-js/webpack.prod.js b/packages/core-js/webpack.prod.js index 6381b1fc..3a1f93ac 100644 --- a/packages/core-js/webpack.prod.js +++ b/packages/core-js/webpack.prod.js @@ -4,6 +4,11 @@ const common = require('./webpack.common'); const prodConfig = { mode: 'production', devtool: 'source-map', + output: { + library: { + type: 'umd', + }, + }, optimization: { splitChunks: { chunks: 'all', diff --git a/packages/editor/cypress/e2e/topicShape.cy.ts b/packages/editor/cypress/e2e/topicShape.cy.ts index 10e9d920..132a89c1 100644 --- a/packages/editor/cypress/e2e/topicShape.cy.ts +++ b/packages/editor/cypress/e2e/topicShape.cy.ts @@ -74,7 +74,7 @@ describe('Topic Shape Suite', () => { .invoke('attr', 'rx') .then(parseInt) .should('be.a', 'number') - .should('be.gte', 12); + .should('be.gte', 11); cy.get('[test-id=2] > rect') .eq(1) .invoke('attr', 'rx') diff --git a/packages/editor/cypress/snapshots/relationship.cy.ts/addRelationship.snap.png b/packages/editor/cypress/snapshots/relationship.cy.ts/addRelationship.snap.png index bc207983..52906c33 100644 Binary files a/packages/editor/cypress/snapshots/relationship.cy.ts/addRelationship.snap.png and b/packages/editor/cypress/snapshots/relationship.cy.ts/addRelationship.snap.png differ diff --git a/packages/editor/cypress/snapshots/relationship.cy.ts/delete relationship.snap.png b/packages/editor/cypress/snapshots/relationship.cy.ts/delete relationship.snap.png index b12a6545..e958cc64 100644 Binary files a/packages/editor/cypress/snapshots/relationship.cy.ts/delete relationship.snap.png and b/packages/editor/cypress/snapshots/relationship.cy.ts/delete relationship.snap.png differ diff --git a/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 0.snap.png b/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 0.snap.png index fefe0de7..bec552bf 100644 Binary files a/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 0.snap.png and b/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 0.snap.png differ diff --git a/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 1.snap.png b/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 1.snap.png index 42c12b81..4226e868 100644 Binary files a/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 1.snap.png and b/packages/editor/cypress/snapshots/relationship.cy.ts/move ctl pont 1.snap.png differ diff --git a/packages/editor/cypress/snapshots/relationship.cy.ts/rel ctl undo.snap.png b/packages/editor/cypress/snapshots/relationship.cy.ts/rel ctl undo.snap.png index 7245a3de..af5776e8 100644 Binary files a/packages/editor/cypress/snapshots/relationship.cy.ts/rel ctl undo.snap.png and b/packages/editor/cypress/snapshots/relationship.cy.ts/rel ctl undo.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-complex.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-complex.snap.png index 81cc77f0..c42ee9e7 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-complex.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-complex.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-connection-style.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-connection-style.snap.png index 17733163..46881cb4 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-connection-style.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-connection-style.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-emoji.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-emoji.snap.png index 5b60027b..9cc7ea50 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-emoji.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-emoji.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-emptyNodes.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-emptyNodes.snap.png index 5629e772..f790edab 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-emptyNodes.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-emptyNodes.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-error-on-load.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-error-on-load.snap.png index c23a62fc..d338a5a6 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-error-on-load.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-error-on-load.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-huge.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-huge.snap.png index 225195c9..e868e2ff 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-huge.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-huge.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-huge2.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-huge2.snap.png index 2e979fef..af43f66a 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-huge2.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-huge2.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-icon-sample.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-icon-sample.snap.png index 6b677bbe..d1f79d3a 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-icon-sample.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-icon-sample.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-img-support.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-img-support.snap.png index a8b750ce..8fe45304 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-img-support.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-img-support.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-order.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-order.snap.png index 62a43d8e..811517ac 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-order.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-order.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample1.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample1.snap.png index a6c4f6e7..d4fb0b18 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample1.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample1.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample2.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample2.snap.png index 4702ffdd..f4715e7d 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample2.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample2.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample3.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample3.snap.png index 8d944b25..a98335b7 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample3.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample3.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample4.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample4.snap.png index b3d82e07..0fe56d70 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample4.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample4.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample5.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample5.snap.png index dd803a69..d1ae02b4 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample5.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample5.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample6.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample6.snap.png index df550c7f..75adfe82 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample6.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample6.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample8.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample8.snap.png index 07d0019b..b54544ca 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample8.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-sample8.snap.png differ diff --git a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-welcome.snap.png b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-welcome.snap.png index 7f4b08e0..e2c82253 100644 Binary files a/packages/editor/cypress/snapshots/renderAll.cy.ts/map-welcome.snap.png and b/packages/editor/cypress/snapshots/renderAll.cy.ts/map-welcome.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/moveDefaultPosition.snap.png b/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/moveDefaultPosition.snap.png index 3dd0bd57..763e0ad4 100644 Binary files a/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/moveDefaultPosition.snap.png and b/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/moveDefaultPosition.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/movedownNode.snap.png b/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/movedownNode.snap.png index dbd43860..85c39c1a 100644 Binary files a/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/movedownNode.snap.png and b/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/movedownNode.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/moveleftNode.snap.png b/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/moveleftNode.snap.png index 8a1860e6..4c63b69a 100644 Binary files a/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/moveleftNode.snap.png and b/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/moveleftNode.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/moveupNode.snap.png b/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/moveupNode.snap.png index 03ac0438..1dc89164 100644 Binary files a/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/moveupNode.snap.png and b/packages/editor/cypress/snapshots/topicDragAndDrop.cy.ts/moveupNode.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontBold.snap.png b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontBold.snap.png index b5eb77fa..99255db8 100644 Binary files a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontBold.snap.png and b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontBold.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontColor.snap.png b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontColor.snap.png index 8c383abd..3c5c27fb 100644 Binary files a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontColor.snap.png and b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontColor.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontItalic.snap.png b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontItalic.snap.png index 670d2c2b..3c236039 100644 Binary files a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontItalic.snap.png and b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontItalic.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeHuge.snap.png b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeHuge.snap.png index 4ae2aacd..06fbdc84 100644 Binary files a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeHuge.snap.png and b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeHuge.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeLarge.snap.png b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeLarge.snap.png index 5c48a8fc..c808d124 100644 Binary files a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeLarge.snap.png and b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeLarge.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeNormal.snap.png b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeNormal.snap.png index c9588682..2a119f85 100644 Binary files a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeNormal.snap.png and b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeNormal.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeSmall.snap.png b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeSmall.snap.png index 02f89f60..47c93bb8 100644 Binary files a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeSmall.snap.png and b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeFontSizeSmall.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeMainTopicText.snap.png b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeMainTopicText.snap.png index ee513f76..442d81eb 100644 Binary files a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeMainTopicText.snap.png and b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/changeMainTopicText.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/fontShapePanel.snap.png b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/fontShapePanel.snap.png index c2f868f1..8535a402 100644 Binary files a/packages/editor/cypress/snapshots/topicFontChange.cy.ts/fontShapePanel.snap.png and b/packages/editor/cypress/snapshots/topicFontChange.cy.ts/fontShapePanel.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicIcon.cy.ts/add-new-icon.snap.png b/packages/editor/cypress/snapshots/topicIcon.cy.ts/add-new-icon.snap.png index 3c59f32d..117ce247 100644 Binary files a/packages/editor/cypress/snapshots/topicIcon.cy.ts/add-new-icon.snap.png and b/packages/editor/cypress/snapshots/topicIcon.cy.ts/add-new-icon.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicIcon.cy.ts/icons-pannel.snap.png b/packages/editor/cypress/snapshots/topicIcon.cy.ts/icons-pannel.snap.png index 455a6617..04d2e137 100644 Binary files a/packages/editor/cypress/snapshots/topicIcon.cy.ts/icons-pannel.snap.png and b/packages/editor/cypress/snapshots/topicIcon.cy.ts/icons-pannel.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicManager.cy.ts/addChildNodeSortcut.snap.png b/packages/editor/cypress/snapshots/topicManager.cy.ts/addChildNodeSortcut.snap.png index 2fb9889a..8d34e100 100644 Binary files a/packages/editor/cypress/snapshots/topicManager.cy.ts/addChildNodeSortcut.snap.png and b/packages/editor/cypress/snapshots/topicManager.cy.ts/addChildNodeSortcut.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicManager.cy.ts/deleteTopicShortcut.snap.png b/packages/editor/cypress/snapshots/topicManager.cy.ts/deleteTopicShortcut.snap.png index 313b5924..587e03b8 100644 Binary files a/packages/editor/cypress/snapshots/topicManager.cy.ts/deleteTopicShortcut.snap.png and b/packages/editor/cypress/snapshots/topicManager.cy.ts/deleteTopicShortcut.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicManager.cy.ts/editor-shortcut-edit.snap.png b/packages/editor/cypress/snapshots/topicManager.cy.ts/editor-shortcut-edit.snap.png index a359e689..b8ded9b7 100644 Binary files a/packages/editor/cypress/snapshots/topicManager.cy.ts/editor-shortcut-edit.snap.png and b/packages/editor/cypress/snapshots/topicManager.cy.ts/editor-shortcut-edit.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicManager.cy.ts/redoChange.snap.png b/packages/editor/cypress/snapshots/topicManager.cy.ts/redoChange.snap.png index a597a7b2..9a77cf9c 100644 Binary files a/packages/editor/cypress/snapshots/topicManager.cy.ts/redoChange.snap.png and b/packages/editor/cypress/snapshots/topicManager.cy.ts/redoChange.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicManager.cy.ts/saveChagesShortcut.snap.png b/packages/editor/cypress/snapshots/topicManager.cy.ts/saveChagesShortcut.snap.png index 27dd61bf..5b570f55 100644 Binary files a/packages/editor/cypress/snapshots/topicManager.cy.ts/saveChagesShortcut.snap.png and b/packages/editor/cypress/snapshots/topicManager.cy.ts/saveChagesShortcut.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicManager.cy.ts/undoChange.snap.png b/packages/editor/cypress/snapshots/topicManager.cy.ts/undoChange.snap.png index 4fd147e9..c78e5ca3 100644 Binary files a/packages/editor/cypress/snapshots/topicManager.cy.ts/undoChange.snap.png and b/packages/editor/cypress/snapshots/topicManager.cy.ts/undoChange.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToEllipseShape.snap.png b/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToEllipseShape.snap.png index d54cdbdb..4e2d4042 100644 Binary files a/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToEllipseShape.snap.png and b/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToEllipseShape.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToLine.snap.png b/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToLine.snap.png index 57036341..7121f2dc 100644 Binary files a/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToLine.snap.png and b/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToLine.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToRoundedRectangle.snap.png b/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToRoundedRectangle.snap.png index bc38faad..6bd7fccf 100644 Binary files a/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToRoundedRectangle.snap.png and b/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToRoundedRectangle.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToSquareShape.snap.png b/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToSquareShape.snap.png index 70564329..78343407 100644 Binary files a/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToSquareShape.snap.png and b/packages/editor/cypress/snapshots/topicShape.cy.ts/changeToSquareShape.snap.png differ diff --git a/packages/editor/cypress/snapshots/topicShape.cy.ts/topicShapePanel.snap.png b/packages/editor/cypress/snapshots/topicShape.cy.ts/topicShapePanel.snap.png index 6a737c15..f7df302d 100644 Binary files a/packages/editor/cypress/snapshots/topicShape.cy.ts/topicShapePanel.snap.png and b/packages/editor/cypress/snapshots/topicShape.cy.ts/topicShapePanel.snap.png differ diff --git a/packages/editor/package.json b/packages/editor/package.json index ad40a14c..5efd9458 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -3,6 +3,7 @@ "version": "0.4.2", "main": "dist/editor.bundle.js", "scripts": { + "bootstrap": "yalc publish;yalc add @wisemapping/mindplot", "build": "webpack --config webpack.prod.js", "playground": "webpack serve --config webpack.playground.js", "cy:run": "cypress run", diff --git a/packages/mindplot/babel.config.json b/packages/mindplot/babel.config.json index 60fe625d..a4b509d0 100644 --- a/packages/mindplot/babel.config.json +++ b/packages/mindplot/babel.config.json @@ -11,8 +11,5 @@ "@babel/preset-typescript" ] ], - "plugins": [ - "@babel/plugin-proposal-class-properties" - ], "sourceType": "module" } \ No newline at end of file diff --git a/packages/mindplot/cypress.config.js b/packages/mindplot/cypress.config.js index c987b627..8c5dca2c 100644 --- a/packages/mindplot/cypress.config.js +++ b/packages/mindplot/cypress.config.js @@ -10,7 +10,7 @@ module.exports = defineConfig({ setupNodeEvents(on, config) { return require('./cypress/plugins/index.js')(on, config) }, - baseUrl: 'http://localhost:8083', - specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}', + baseUrl: 'http://localhost:6006', + specPattern: 'cypress/e2e/**/*.{js,ts}', }, }) diff --git a/packages/mindplot/cypress/e2e/layout.test.js b/packages/mindplot/cypress/e2e/layout.test.js new file mode 100644 index 00000000..fcf4d4f5 --- /dev/null +++ b/packages/mindplot/cypress/e2e/layout.test.js @@ -0,0 +1,7 @@ +context('Layout suite', () => { + it('basic layout', () => { + cy.visit('/iframe.html?args=&id=mindplot-layout--basic-suite&viewMode=story'); + cy.wait(2000); + cy.matchImageSnapshot('layout-suite'); + }); +}); diff --git a/packages/mindplot/cypress/e2e/playground.test.js b/packages/mindplot/cypress/e2e/playground.test.js deleted file mode 100644 index b39f0fb0..00000000 --- a/packages/mindplot/cypress/e2e/playground.test.js +++ /dev/null @@ -1,11 +0,0 @@ -context('Playground', () => { - it('the playground layout page should match its snapshot', () => { - // TODO: check why this error is happening, and remove this handling - cy.on('uncaught:exception', (err) => { - expect(err.message).to.include('Prediction is incorrectly positioned'); - return false; - }); - cy.visit('/layout.html'); - cy.matchImageSnapshot('layout'); - }); -}); diff --git a/packages/mindplot/cypress/e2e/topic.test.js b/packages/mindplot/cypress/e2e/topic.test.js new file mode 100644 index 00000000..cef9a7df --- /dev/null +++ b/packages/mindplot/cypress/e2e/topic.test.js @@ -0,0 +1,36 @@ +context('Topic suite', () => { + it('topic border', () => { + cy.visit('/iframe.html?args=&id=mindplot-topic--border-style&viewMode=story'); + cy.matchImageSnapshot('topic-border'); + }); + + it('topic style', () => { + cy.visit('/iframe.html?args=&id=mindplot-topic--font-style&viewMode=story'); + cy.matchImageSnapshot('topic-style'); + }); + + it('topic color', () => { + cy.visit('/iframe.html?args=&id=mindplot-topic--background-color&viewMode=story'); + cy.matchImageSnapshot('topic-color'); + }); + it('topic note', () => { + cy.visit('/iframe.html?args=&id=mindplot-topic--note-feature&viewMode=story'); + cy.matchImageSnapshot('topic-note'); + }); + it('topic link feature', () => { + cy.visit('/iframe.html?args=&id=mindplot-topic--link-feature&viewMode=story'); + cy.matchImageSnapshot('topic-link-feature'); + }); + it('topic icon feature', () => { + cy.visit('/iframe.html?args=&id=mindplot-topic--icon-feature&viewMode=story'); + cy.matchImageSnapshot('topic-icon-feature'); + }); + it('topic shape line', () => { + cy.visit('/iframe.html?args=&id=mindplot-topic--shape-line&viewMode=story'); + cy.matchImageSnapshot('topic-shape-line'); + }); + it('topic ellipse line', () => { + cy.visit('/iframe.html?args=&id=mindplot-topic--shape-ellipse&viewMode=story'); + cy.matchImageSnapshot('topic-shape-ellipse'); + }); +}); diff --git a/packages/mindplot/cypress/snapshots/layout.test.js/layout-suite.snap.png b/packages/mindplot/cypress/snapshots/layout.test.js/layout-suite.snap.png new file mode 100644 index 00000000..10d3691d Binary files /dev/null and b/packages/mindplot/cypress/snapshots/layout.test.js/layout-suite.snap.png differ diff --git a/packages/mindplot/cypress/snapshots/playground.test.js/__diff_output__/layout.diff.png b/packages/mindplot/cypress/snapshots/playground.test.js/__diff_output__/layout.diff.png deleted file mode 100644 index 4a2d3236..00000000 Binary files a/packages/mindplot/cypress/snapshots/playground.test.js/__diff_output__/layout.diff.png and /dev/null differ diff --git a/packages/mindplot/cypress/snapshots/playground.test.js/layout.snap.png b/packages/mindplot/cypress/snapshots/playground.test.js/layout.snap.png deleted file mode 100644 index dff2a26b..00000000 Binary files a/packages/mindplot/cypress/snapshots/playground.test.js/layout.snap.png and /dev/null differ diff --git a/packages/mindplot/cypress/snapshots/playground.test.js/viewmode.snap.png b/packages/mindplot/cypress/snapshots/playground.test.js/viewmode.snap.png deleted file mode 100644 index a58c473d..00000000 Binary files a/packages/mindplot/cypress/snapshots/playground.test.js/viewmode.snap.png and /dev/null differ diff --git a/packages/mindplot/cypress/snapshots/topic.test.js/topic-border.snap.png b/packages/mindplot/cypress/snapshots/topic.test.js/topic-border.snap.png new file mode 100644 index 00000000..8e266884 Binary files /dev/null and b/packages/mindplot/cypress/snapshots/topic.test.js/topic-border.snap.png differ diff --git a/packages/mindplot/cypress/snapshots/topic.test.js/topic-color.snap.png b/packages/mindplot/cypress/snapshots/topic.test.js/topic-color.snap.png new file mode 100644 index 00000000..a5a2b833 Binary files /dev/null and b/packages/mindplot/cypress/snapshots/topic.test.js/topic-color.snap.png differ diff --git a/packages/mindplot/cypress/snapshots/topic.test.js/topic-icon-feature.snap.png b/packages/mindplot/cypress/snapshots/topic.test.js/topic-icon-feature.snap.png new file mode 100644 index 00000000..70d7fc6f Binary files /dev/null and b/packages/mindplot/cypress/snapshots/topic.test.js/topic-icon-feature.snap.png differ diff --git a/packages/mindplot/cypress/snapshots/topic.test.js/topic-link-feature.snap.png b/packages/mindplot/cypress/snapshots/topic.test.js/topic-link-feature.snap.png new file mode 100644 index 00000000..a6388c4f Binary files /dev/null and b/packages/mindplot/cypress/snapshots/topic.test.js/topic-link-feature.snap.png differ diff --git a/packages/mindplot/cypress/snapshots/topic.test.js/topic-note.snap.png b/packages/mindplot/cypress/snapshots/topic.test.js/topic-note.snap.png new file mode 100644 index 00000000..d95049d8 Binary files /dev/null and b/packages/mindplot/cypress/snapshots/topic.test.js/topic-note.snap.png differ diff --git a/packages/mindplot/cypress/snapshots/topic.test.js/topic-shape-ellipse.snap.png b/packages/mindplot/cypress/snapshots/topic.test.js/topic-shape-ellipse.snap.png new file mode 100644 index 00000000..329cd303 Binary files /dev/null and b/packages/mindplot/cypress/snapshots/topic.test.js/topic-shape-ellipse.snap.png differ diff --git a/packages/mindplot/cypress/snapshots/topic.test.js/topic-shape-line.snap.png b/packages/mindplot/cypress/snapshots/topic.test.js/topic-shape-line.snap.png new file mode 100644 index 00000000..27aaa737 Binary files /dev/null and b/packages/mindplot/cypress/snapshots/topic.test.js/topic-shape-line.snap.png differ diff --git a/packages/mindplot/cypress/snapshots/topic.test.js/topic-style.snap.png b/packages/mindplot/cypress/snapshots/topic.test.js/topic-style.snap.png new file mode 100644 index 00000000..98d74e5d Binary files /dev/null and b/packages/mindplot/cypress/snapshots/topic.test.js/topic-style.snap.png differ diff --git a/packages/mindplot/cypress/support/e2e.js b/packages/mindplot/cypress/support/e2e.js index 37a498fb..7bfe4a73 100644 --- a/packages/mindplot/cypress/support/e2e.js +++ b/packages/mindplot/cypress/support/e2e.js @@ -16,5 +16,14 @@ // Import commands.js using ES2015 syntax: import './commands'; -// Alternatively you can use CommonJS syntax: -// require('./commands') +Cypress.on('window:before:load', (win) => { + cy.spy(win.console, 'error'); + cy.spy(win.console, 'warn'); +}); + +afterEach(() => { + cy.window().then((win) => { + expect(win.console.error).to.have.callCount(0); + expect(win.console.warn).to.have.callCount(0); + }); +}); diff --git a/packages/mindplot/jest.config.js b/packages/mindplot/jest.config.js index a3831d95..75e4ef64 100644 --- a/packages/mindplot/jest.config.js +++ b/packages/mindplot/jest.config.js @@ -4,7 +4,8 @@ const config = { preset: 'ts-jest', moduleFileExtensions: ['js', 'ts'], transform: { - '^.+\\.js?$': 'babel-jest', + '^.+\\.(ts)?$': 'ts-jest', + '^.+\\.(js)$': 'babel-jest', }, }; diff --git a/libraries/jquery.hotkeys.js b/packages/mindplot/libraries/jquery.hotkeys.js similarity index 100% rename from libraries/jquery.hotkeys.js rename to packages/mindplot/libraries/jquery.hotkeys.js diff --git a/libraries/jquery.touchevent.js b/packages/mindplot/libraries/jquery.touchevent.js similarity index 100% rename from libraries/jquery.touchevent.js rename to packages/mindplot/libraries/jquery.touchevent.js diff --git a/packages/mindplot/package.json b/packages/mindplot/package.json index 951f577d..e8991077 100644 --- a/packages/mindplot/package.json +++ b/packages/mindplot/package.json @@ -10,8 +10,7 @@ "main": "src/index.ts", "files": [ "src", - "assets", - "dist" + "assets" ], "publishConfig": { "registry": "https://registry.yarnpkg.com" @@ -21,16 +20,16 @@ "url": "git@bitbucket.org:wisemapping/wisemapping-frontend.git" }, "scripts": { + "bootstrap": "yalc publish;yalc add @wisemapping/core-js;yalc add @wisemapping/web2d", "build": "webpack --config webpack.prod.js", "dev": "webpack serve --config webpack.dev.js", "lint": "eslint src --ext js,ts", - "playground": "webpack serve --config webpack.playground.js", "cy:run": "cypress run", "cy:open": "cypress open", - "test:unit": "jest ./test/unit/export/*.ts ./test/unit/import/*.ts ./test/unit/layout/*.js --verbose --silent --detectOpenHandles", - "test:integration": "start-server-and-test playground http-get://localhost:8083 cy:run", + "test:unit": "jest ./test/unit/export/*.ts ./test/unit/import/*.ts --verbose --silent --detectOpenHandles", + "test:integration": "start-server-and-test storybook http-get://localhost:6006 cy:run", "test": "yarn test:unit && yarn test:integration", - "storybook": "start-storybook -p 6006", + "storybook": "start-storybook -p 6006 --no-open", "build-storybook": "build-storybook" }, "dependencies": { @@ -58,6 +57,8 @@ "blob-polyfill": "^6.0.20211015", "cypress": "^12.3.0", "cypress-image-snapshot": "^4.0.1", - "mocha": "^9.1.3" + "jest": "^29.4.1", + "mocha": "^9.1.3", + "start-server-and-test": "^1.15.3" } } diff --git a/packages/mindplot/src/components/ActionDispatcher.ts b/packages/mindplot/src/components/ActionDispatcher.ts index 5ed213bc..202f04dd 100644 --- a/packages/mindplot/src/components/ActionDispatcher.ts +++ b/packages/mindplot/src/components/ActionDispatcher.ts @@ -18,7 +18,6 @@ * limitations under the License. */ import { $assert } from '@wisemapping/core-js'; -import Point from '@wisemapping/web2d'; import { Mindmap } from '..'; import CommandContext from './CommandContext'; import { PivotType } from './RelationshipControlPoints'; @@ -51,12 +50,12 @@ abstract class ActionDispatcher extends Events { abstract dragTopic( topicId: number, - position: Point, + position: PositionType, order: number | null, parentTopic: Topic | null, ): void; - abstract moveTopic(topicId: number, position: Point): void; + abstract moveTopic(topicId: number, position: PositionType): void; abstract moveControlPoint( model: RelationshipModel, diff --git a/packages/mindplot/src/components/Workspace.ts b/packages/mindplot/src/components/Canvas.ts similarity index 77% rename from packages/mindplot/src/components/Workspace.ts rename to packages/mindplot/src/components/Canvas.ts index 0f45bab3..9f7e9cf8 100644 --- a/packages/mindplot/src/components/Workspace.ts +++ b/packages/mindplot/src/components/Canvas.ts @@ -15,12 +15,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { $assert, $defined } from '@wisemapping/core-js'; -import { Workspace as Workspace2D, ElementClass as Element2D } from '@wisemapping/web2d'; +import { $assert } from '@wisemapping/core-js'; +import { Workspace as Workspace2D, ElementClass, ElementPeer } from '@wisemapping/web2d'; import ScreenManager from './ScreenManager'; import SizeType from './SizeType'; +import CanvasElement from './CanvasElement'; -class Workspace { +class Canvas { private _zoom: number; private _screenManager: ScreenManager; @@ -35,10 +36,14 @@ class Workspace { private _visibleAreaSize!: SizeType; - private _renderQueue: Element2D[]; + private _renderQueue: (ElementClass | CanvasElement)[]; private _queueRenderEnabled: boolean; + private _mouseMoveListener; + + private _mouseUpListener; + constructor(screenManager: ScreenManager, zoom: number, isReadOnly: boolean) { // Create a suitable container ... $assert(screenManager, 'Div container can not be null'); @@ -64,6 +69,8 @@ class Workspace { this._renderQueue = []; this._eventsEnabled = false; this._queueRenderEnabled = false; + this._mouseMoveListener = null; + this._mouseUpListener = null; } private _adjustWorkspace(): void { @@ -105,7 +112,7 @@ class Workspace { return new Workspace2D(workspaceProfile); } - append(shape: Element2D): void { + append(shape: ElementClass | CanvasElement): void { if (this._queueRenderEnabled) { this._renderQueue.push(shape); } else { @@ -113,11 +120,12 @@ class Workspace { } } - private appendInternal(shape: Element2D): void { - if (shape.addToWorkspace) { - shape.addToWorkspace(this); + private appendInternal(shape: CanvasElement | ElementClass): void { + // eslint-disable-next-line no-prototype-builtins, dot-notation + if (typeof shape['addToWorkspace'] === 'function') { + (shape as CanvasElement).addToWorkspace(this); } else { - this._workspace.append(shape); + this._workspace.append(shape as ElementClass); } } @@ -127,7 +135,7 @@ class Workspace { let result = Promise.resolve(); if (!value) { // eslint-disable-next-line arrow-body-style - result = Workspace.delay(100).then(() => { + result = Canvas.delay(100).then(() => { return this.processRenderQueue(this._renderQueue.reverse(), 300); }); } @@ -138,29 +146,35 @@ class Workspace { return new Promise((resolve) => setTimeout(resolve, t)); } - private processRenderQueue(renderQueue: Element2D[], batch: number): Promise { + private processRenderQueue( + renderQueue: (ElementClass | CanvasElement)[], + batch: number, + ): Promise { let result: Promise; - if (renderQueue.length > 0) { - result = new Promise((resolve: (queue: Element2D[]) => void) => { - for (let i = 0; i < batch && renderQueue.length > 0; i++) { - const elem = renderQueue.pop(); - this.appendInternal(elem); - } - resolve(renderQueue); - }).then((queue) => Workspace.delay(30).then(() => this.processRenderQueue(queue, batch))); + if (renderQueue.length > 0) { + result = new Promise( + (resolve: (queue: (ElementClass | CanvasElement)[]) => void) => { + for (let i = 0; i < batch && renderQueue.length > 0; i++) { + const elem = renderQueue.pop()!; + this.appendInternal(elem); + } + + resolve(renderQueue); + }, + ).then((queue) => Canvas.delay(30).then(() => this.processRenderQueue(queue, batch))); } else { result = Promise.resolve(); } return result; } - removeChild(shape: Element2D): void { - // Element is a node, not a web2d element? - if (shape.removeFromWorkspace) { - shape.removeFromWorkspace(this); + removeChild(shape: ElementClass | CanvasElement): void { + // eslint-disable-next-line dot-notation + if (typeof shape['removeFromWorkspace'] === 'function') { + (shape as CanvasElement).removeFromWorkspace(this); } else { - this._workspace.removeChild(shape); + this._workspace.removeChild(shape as ElementClass); } } @@ -244,7 +258,7 @@ class Workspace { return this._eventsEnabled; } - getSVGElement() { + getSVGElement(): Element { return this._workspace.getSVGElement(); } @@ -252,8 +266,8 @@ class Workspace { const workspace = this._workspace; const screenManager = this._screenManager; const mWorkspace = this; - const mouseDownListener = function mouseDownListener(event: MouseEvent) { - if (!$defined(workspace._mouseMoveListener)) { + const mouseDownListener = (event: MouseEvent) => { + if (!this._mouseMoveListener) { if (mWorkspace.isWorkspaceEventsEnabled()) { mWorkspace.enableWorkspaceEvents(false); @@ -261,7 +275,7 @@ class Workspace { const originalCoordOrigin = workspace.getCoordOrigin(); let wasDragged = false; - workspace._mouseMoveListener = (mouseMoveEvent: MouseEvent) => { + this._mouseMoveListener = (mouseMoveEvent: MouseEvent) => { const currentMousePosition = screenManager.getWorkspaceMousePosition(mouseMoveEvent); const offsetX = currentMousePosition.x - mouseDownPosition.x; @@ -284,17 +298,17 @@ class Workspace { screenManager.fireEvent('update'); wasDragged = true; }; - screenManager.addEvent('mousemove', workspace._mouseMoveListener); - screenManager.addEvent('touchmove', workspace._mouseMoveListener); + screenManager.addEvent('mousemove', this._mouseMoveListener); + screenManager.addEvent('touchmove', this._mouseMoveListener); // Register mouse up listeners ... - workspace._mouseUpListener = () => { - screenManager.removeEvent('mousemove', workspace._mouseMoveListener); - screenManager.removeEvent('mouseup', workspace._mouseUpListener); - screenManager.removeEvent('touchmove', workspace._mouseUpListener); - screenManager.removeEvent('touchend', workspace._mouseMoveListener); - workspace._mouseUpListener = null; - workspace._mouseMoveListener = null; + this._mouseUpListener = () => { + screenManager.removeEvent('mousemove', this._mouseMoveListener); + screenManager.removeEvent('mouseup', this._mouseUpListener); + screenManager.removeEvent('touchmove', this._mouseUpListener); + screenManager.removeEvent('touchend', this._mouseMoveListener); + this._mouseUpListener = null; + this._mouseMoveListener = null; window.document.body.style.cursor = 'default'; // Update screen manager offset. @@ -306,11 +320,11 @@ class Workspace { screenManager.fireEvent('click'); } }; - screenManager.addEvent('mouseup', workspace._mouseUpListener); - screenManager.addEvent('touchend', workspace._mouseUpListener); + screenManager.addEvent('mouseup', this._mouseUpListener); + screenManager.addEvent('touchend', this._mouseUpListener); } } else { - workspace._mouseUpListener(); + this._mouseUpListener(); } }; screenManager.addEvent('mousedown', mouseDownListener); @@ -322,4 +336,4 @@ class Workspace { } } -export default Workspace; +export default Canvas; diff --git a/packages/mindplot/src/components/CanvasElement.ts b/packages/mindplot/src/components/CanvasElement.ts new file mode 100644 index 00000000..627f74c5 --- /dev/null +++ b/packages/mindplot/src/components/CanvasElement.ts @@ -0,0 +1,9 @@ +import Canvas from './Canvas'; + +interface CanvasElement { + addToWorkspace(workspace: Canvas): void; + + removeFromWorkspace(workspace: Canvas): void; +} + +export default CanvasElement; diff --git a/packages/mindplot/src/components/CentralTopic.ts b/packages/mindplot/src/components/CentralTopic.ts index 13b0f0cc..b7cc9c6b 100644 --- a/packages/mindplot/src/components/CentralTopic.ts +++ b/packages/mindplot/src/components/CentralTopic.ts @@ -15,18 +15,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Point } from '@wisemapping/web2d'; import { $assert } from '@wisemapping/core-js'; +import PositionType from './PositionType'; import Topic from './Topic'; import Shape from './util/Shape'; class CentralTopic extends Topic { - _buildDragShape() { + buildDragShape() { // Ignore .. } - _registerEvents(): void { - super._registerEvents(); + registerEvents(): void { + super.registerEvents(); // This disable the drag of the central topic. // But solves the problem of deselecting the nodes when the screen is clicked. @@ -35,29 +35,29 @@ class CentralTopic extends Topic { }); } - workoutIncomingConnectionPoint(): Point { + workoutIncomingConnectionPoint(): PositionType { return this.getPosition(); } - setCursor(type: string) { + setCursor(type: string): void { super.setCursor(type === 'move' ? 'default' : type); } - updateTopicShape() { + updateTopicShape(): void { // Overwite behaviour ... } _updatePositionOnChangeSize(): void { // Center main topic ... - const zeroPoint = new Point(0, 0); + const zeroPoint = { x: 0, y: 0 }; this.setPosition(zeroPoint); } - getShrinkConnector() { + getShrinkConnector(): null { return null; } - workoutOutgoingConnectionPoint(targetPosition: Point) { + workoutOutgoingConnectionPoint(targetPosition: PositionType) { $assert(targetPosition, 'targetPoint can not be null'); const pos = this.getPosition(); diff --git a/packages/mindplot/src/components/CommandContext.ts b/packages/mindplot/src/components/CommandContext.ts index 1001cf8a..d5e6b4aa 100644 --- a/packages/mindplot/src/components/CommandContext.ts +++ b/packages/mindplot/src/components/CommandContext.ts @@ -16,11 +16,11 @@ * limitations under the License. */ import { $assert, $defined } from '@wisemapping/core-js'; -import Point from '@wisemapping/web2d'; import { Designer } from '..'; import EventBus from './layout/EventBus'; import NodeModel from './model/NodeModel'; import RelationshipModel from './model/RelationshipModel'; +import PositionType from './PositionType'; import Relationship from './Relationship'; import Topic from './Topic'; @@ -102,7 +102,7 @@ class CommandContext { } /** */ - moveTopic(topic: Topic, position: Point): void { + moveTopic(topic: Topic, position: PositionType): void { $assert(topic, 'topic cannot be null'); $assert(position, 'position cannot be null'); EventBus.instance.fireEvent('topicMoved', { diff --git a/packages/mindplot/src/components/ConnectionLine.ts b/packages/mindplot/src/components/ConnectionLine.ts index 182efdc4..dc12200b 100644 --- a/packages/mindplot/src/components/ConnectionLine.ts +++ b/packages/mindplot/src/components/ConnectionLine.ts @@ -17,10 +17,11 @@ */ import { $assert } from '@wisemapping/core-js'; -import { CurvedLine, PolyLine, Line } from '@wisemapping/web2d'; +import { CurvedLine, Line, PolyLine } from '@wisemapping/web2d'; +import PositionType from './PositionType'; import Topic from './Topic'; import TopicConfig from './TopicConfig'; -import Workspace from './Workspace'; +import Canvas from './Canvas'; // eslint-disable-next-line no-shadow export enum LineType { @@ -51,7 +52,7 @@ class ConnectionLine { this._color = this.updateColor(); } - private _getCtrlPoints(sourceNode: Topic, targetNode: Topic) { + private _getCtrlPoints(sourceNode: Topic, targetNode: Topic): [PositionType, PositionType] { const srcPos = sourceNode.workoutOutgoingConnectionPoint(targetNode.getPosition()); const destPos = targetNode.workoutIncomingConnectionPoint(sourceNode.getPosition()); const deltaX = (srcPos.x - destPos.x) / 3; @@ -61,8 +62,8 @@ class ConnectionLine { ]; } - protected createLine(lineType: LineType): ConnectionLine { - let line: ConnectionLine; + protected createLine(lineType: LineType): Line { + let line: Line; switch (lineType) { case LineType.POLYLINE_MIDDLE: line = new PolyLine(); @@ -142,8 +143,8 @@ class ConnectionLine { if (this._type === LineType.THICK_CURVED || this._type === LineType.THIN_CURVED) { const ctrlPoints = this._getCtrlPoints(this._sourceTopic, this._targetTopic); - line2d.setSrcControlPoint(ctrlPoints[0]); - line2d.setDestControlPoint(ctrlPoints[1]); + (line2d as CurvedLine).setSrcControlPoint(ctrlPoints[0]); + (line2d as CurvedLine).setDestControlPoint(ctrlPoints[1]); } // Add connector ... @@ -179,7 +180,7 @@ class ConnectionLine { } setStroke(color: string, style: string, opacity: number) { - this._line.setStroke(null, null, color, opacity); + this._line.setStroke(1, style, color, opacity); this._color = color; } @@ -187,13 +188,13 @@ class ConnectionLine { return this._color; } - addToWorkspace(workspace: Workspace) { - workspace.append(this._line); + addToWorkspace(workspace: Canvas) { + workspace.append(this._line.getElementClass()); this._line.moveToBack(); } - removeFromWorkspace(workspace: Workspace) { - workspace.removeChild(this._line); + removeFromWorkspace(workspace: Canvas) { + workspace.removeChild(this._line.getElementClass()); } getTargetTopic(): Topic { diff --git a/packages/mindplot/src/components/Designer.ts b/packages/mindplot/src/components/Designer.ts index 504f95a6..365bc388 100644 --- a/packages/mindplot/src/components/Designer.ts +++ b/packages/mindplot/src/components/Designer.ts @@ -18,7 +18,6 @@ import $ from 'jquery'; import { $assert, $defined } from '@wisemapping/core-js'; -import Point from '@wisemapping/web2d'; import Messages, { $msg } from './Messages'; import Events from './Events'; @@ -31,7 +30,7 @@ import DesignerModel from './DesignerModel'; import DesignerKeyboard from './DesignerKeyboard'; import ScreenManager from './ScreenManager'; -import Workspace from './Workspace'; +import Canvas from './Canvas'; import DragConnector from './DragConnector'; import DragManager from './DragManager'; @@ -60,6 +59,7 @@ import { TopicShapeType } from './model/INodeModel'; import { LineType } from './ConnectionLine'; import XMLSerializerFactory from './persistence/XMLSerializerFactory'; import ImageExpoterFactory from './export/ImageExporterFactory'; +import PositionType from './PositionType'; class Designer extends Events { private _mindmap: Mindmap | null; @@ -70,7 +70,7 @@ class Designer extends Events { private _model: DesignerModel; - private _workspace: Workspace; + private _workspace: Canvas; _eventBussDispatcher: EventBusDispatcher; @@ -108,7 +108,7 @@ class Designer extends Events { // Init Screen manager.. const screenManager = new ScreenManager(divElem); - this._workspace = new Workspace(screenManager, this._model.getZoom(), this.isReadOnly()); + this._workspace = new Canvas(screenManager, this._model.getZoom(), this.isReadOnly()); // Init layout manager ... this._eventBussDispatcher = new EventBusDispatcher(); @@ -200,7 +200,7 @@ class Designer extends Events { }); } - private _buildDragManager(workspace: Workspace): DragManager { + private _buildDragManager(workspace: Canvas): DragManager { const designerModel = this.getModel(); const dragConnector = new DragConnector(designerModel, this._workspace); const dragManager = new DragManager(workspace, this._eventBussDispatcher); @@ -504,7 +504,7 @@ class Designer extends Events { this._actionDispatcher.addTopics([childModel], [parentTopicId]); } - private _createChildModel(topic: Topic, mousePos: Point = null): NodeModel { + private _createChildModel(topic: Topic, mousePos?: PositionType): NodeModel { // Create a new node ... const parentModel = topic.getModel(); const mindmap = parentModel.getMindmap(); @@ -517,7 +517,7 @@ class Designer extends Events { // Create a new node ... const layoutManager = this._eventBussDispatcher.getLayoutManager(); - const result = layoutManager.predict(topic.getId(), null, mousePos); + const result = layoutManager.predict(topic.getId(), null, mousePos || null); childModel.setOrder(result.order); const { position } = result; @@ -949,7 +949,7 @@ class Designer extends Events { this.onObjectFocusEvent(node); } - getWorkSpace(): Workspace { + getWorkSpace(): Canvas { return this._workspace; } diff --git a/packages/mindplot/src/components/DesignerKeyboard.ts b/packages/mindplot/src/components/DesignerKeyboard.ts index 31f3b7f8..bc29d58f 100644 --- a/packages/mindplot/src/components/DesignerKeyboard.ts +++ b/packages/mindplot/src/components/DesignerKeyboard.ts @@ -21,7 +21,7 @@ import Keyboard from './Keyboard'; import { Designer } from '..'; import Topic from './Topic'; -import initHotKeyPluggin from '../../../../libraries/jquery.hotkeys'; +import initHotKeyPluggin from '../../libraries/jquery.hotkeys'; // Provides dispatcher of keyevents by key... initHotKeyPluggin($); @@ -262,7 +262,7 @@ class DesignerKeyboard extends Keyboard { const children = node.getChildren(); if (children.length > 0) { let target = children[0]; - let top = null; + let top: number | null = null; for (let i = 0; i < children.length; i++) { const child = children[i]; const childY = child.getPosition().y; diff --git a/packages/mindplot/src/components/DragConnector.ts b/packages/mindplot/src/components/DragConnector.ts index a28946d7..18c08a9a 100644 --- a/packages/mindplot/src/components/DragConnector.ts +++ b/packages/mindplot/src/components/DragConnector.ts @@ -16,19 +16,19 @@ * limitations under the License. */ import { $assert } from '@wisemapping/core-js'; -import { Point } from '@wisemapping/web2d'; import DesignerModel from './DesignerModel'; import DragTopic from './DragTopic'; import SizeType from './SizeType'; import Topic from './Topic'; -import Workspace from './Workspace'; +import Canvas from './Canvas'; +import PositionType from './PositionType'; class DragConnector { private _designerModel: DesignerModel; - private _workspace: Workspace; + private _workspace: Canvas; - constructor(designerModel: DesignerModel, workspace: Workspace) { + constructor(designerModel: DesignerModel, workspace: Canvas) { $assert(designerModel, 'designerModel can not be null'); $assert(workspace, 'workspace can not be null'); @@ -114,7 +114,7 @@ class DragConnector { private _proximityWeight( isAligned: boolean, target: Topic, - sPos: Point, + sPos: PositionType, currentConnection: Topic, ): number { const tPos = target.getPosition(); @@ -128,8 +128,8 @@ class DragConnector { private _isVerticallyAligned( targetSize: SizeType, - targetPosition: Point, - sourcePosition: Point, + targetPosition: PositionType, + sourcePosition: PositionType, ): boolean { return Math.abs(sourcePosition.y - targetPosition.y) < targetSize.height / 2; } diff --git a/packages/mindplot/src/components/DragManager.ts b/packages/mindplot/src/components/DragManager.ts index 2c14c46e..d8989431 100644 --- a/packages/mindplot/src/components/DragManager.ts +++ b/packages/mindplot/src/components/DragManager.ts @@ -19,10 +19,10 @@ import { $assert } from '@wisemapping/core-js'; import DragTopic from './DragTopic'; import EventBusDispatcher from './layout/EventBusDispatcher'; import Topic from './Topic'; -import Workspace from './Workspace'; +import Canvas from './Canvas'; class DragManager { - private _workspace: Workspace; + private _workspace: Canvas; private _isDragInProcess: boolean; @@ -34,7 +34,7 @@ class DragManager { private _mouseUpListener; - constructor(workspace: Workspace, eventDispatcher: EventBusDispatcher) { + constructor(workspace: Canvas, eventDispatcher: EventBusDispatcher) { this._workspace = workspace; this._listeners = {}; this._isDragInProcess = false; @@ -81,7 +81,7 @@ class DragManager { } protected buildMouseMoveListener( - workspace: Workspace, + workspace: Canvas, dragNode: DragTopic, dragManager: DragManager, ): (event: MouseEvent) => void { @@ -115,7 +115,7 @@ class DragManager { } protected _buildMouseUpListener( - workspace: Workspace, + workspace: Canvas, dragNode: DragTopic, dragManager: DragManager, ) { diff --git a/packages/mindplot/src/components/DragPivot.ts b/packages/mindplot/src/components/DragPivot.ts index 991227b5..abc541e6 100644 --- a/packages/mindplot/src/components/DragPivot.ts +++ b/packages/mindplot/src/components/DragPivot.ts @@ -22,9 +22,10 @@ import PositionType from './PositionType'; import SizeType from './SizeType'; import Topic from './Topic'; import Shape from './util/Shape'; -import Workspace from './Workspace'; +import Canvas from './Canvas'; +import CanvasElement from './CanvasElement'; -class DragPivot { +class DragPivot implements CanvasElement { private _position: PositionType; private _isVisible: boolean; @@ -95,7 +96,7 @@ class DragPivot { // Update Line position. const isAtRight = Shape.isAtRight(targetPosition, position); const pivotPoint = Shape.calculateRectConnectionPoint(position, size, isAtRight); - line.setFrom(pivotPoint.x, pivotPoint.y); + line?.setFrom(pivotPoint.x, pivotPoint.y); // Update rect position const cx = position.x - size.width / 2; @@ -105,7 +106,7 @@ class DragPivot { // 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); + line?.setTo(targetPoint.x, targetPoint.y); } setPosition(point: Point): void { @@ -113,7 +114,7 @@ class DragPivot { this._redrawLine(); } - getPosition(): Point { + getPosition(): PositionType { return this._position; } @@ -157,8 +158,8 @@ class DragPivot { } // If the node is connected, validate that there is a line connecting both... - _getConnectionLine(): CurvedLine { - let result = null; + _getConnectionLine(): CurvedLine | null { + let result: CurvedLine | null = null; const parentTopic = this._targetTopic; if (parentTopic) { if (parentTopic.getType() === 'CentralTopic') { @@ -170,7 +171,7 @@ class DragPivot { return result; } - addToWorkspace(workspace: Workspace) { + addToWorkspace(workspace: Canvas) { const pivotRect = this._getPivotRect(); workspace.append(pivotRect); @@ -196,7 +197,7 @@ class DragPivot { connectRect.moveToBack(); } - removeFromWorkspace(workspace: Workspace) { + removeFromWorkspace(workspace: Canvas) { const shape = this._getPivotRect(); workspace.removeChild(shape); @@ -212,7 +213,7 @@ class DragPivot { } } - connectTo(targetTopic: Topic, position: Point) { + connectTo(targetTopic: Topic, position: PositionType) { $assert(position, 'position can not be null'); $assert(targetTopic, 'parent can not be null'); @@ -242,7 +243,7 @@ class DragPivot { this._redrawLine(); } - disconnect(workspace: Workspace): void { + disconnect(workspace: Canvas): void { $assert(workspace, 'workspace can not be null.'); $assert(this._targetTopic, 'There are not connected topic.'); diff --git a/packages/mindplot/src/components/DragTopic.ts b/packages/mindplot/src/components/DragTopic.ts index 6faa8bbe..f099f54b 100644 --- a/packages/mindplot/src/components/DragTopic.ts +++ b/packages/mindplot/src/components/DragTopic.ts @@ -16,17 +16,19 @@ * limitations under the License. */ import { $assert } from '@wisemapping/core-js'; -import { Point, ElementClass } from '@wisemapping/web2d'; +import { ElementClass, ElementPeer, Group } from '@wisemapping/web2d'; import ActionDispatcher from './ActionDispatcher'; import DragPivot from './DragPivot'; import LayoutManager from './layout/LayoutManager'; import NodeGraph from './NodeGraph'; +import PositionType from './PositionType'; import Topic from './Topic'; -import Workspace from './Workspace'; +import Canvas from './Canvas'; +import CanvasElement from './CanvasElement'; class DragTopic { - private _elem2d: ElementClass; + private _elem2d: Group; private _order: number | null; @@ -34,23 +36,19 @@ class DragTopic { private _layoutManager: LayoutManager; - private _position: Point; + private _position: PositionType; private _isInWorkspace: boolean; static _dragPivot: DragPivot = new DragPivot(); - constructor(dragShape: ElementClass, draggedNode: NodeGraph, layoutManger: LayoutManager) { - $assert(dragShape, 'Rect can not be null.'); - $assert(draggedNode, 'draggedNode can not be null.'); - $assert(layoutManger, 'layoutManger can not be null.'); - + constructor(dragShape: Group, draggedNode: NodeGraph, layoutManger: LayoutManager) { this._elem2d = dragShape; this._order = null; this._draggedNode = draggedNode; this._layoutManager = layoutManger; this._isInWorkspace = false; - this._position = new Point(0, 0); + this._position = { x: 0, y: 0 }; } setOrder(order: number): void { @@ -97,11 +95,11 @@ class DragTopic { return dragPivot.isVisible(); } - getInnerShape(): ElementClass { + getInnerShape(): ElementClass { return this._elem2d; } - disconnect(workspace: Workspace) { + disconnect(workspace: Canvas) { // Clear connection line ... const dragPivot = this._getDragPivot(); dragPivot.disconnect(workspace); @@ -128,7 +126,7 @@ class DragTopic { return this._draggedNode as Topic; } - removeFromWorkspace(workspace: Workspace) { + removeFromWorkspace(workspace: Canvas) { if (this._isInWorkspace) { // Remove drag shadow. workspace.removeChild(this._elem2d); @@ -146,7 +144,7 @@ class DragTopic { return this._isInWorkspace; } - addToWorkspace(workspace: Workspace) { + addToWorkspace(workspace: Canvas) { if (!this._isInWorkspace) { workspace.append(this._elem2d); const dragPivot = this._getDragPivot(); @@ -159,7 +157,7 @@ class DragTopic { return DragTopic._dragPivot; } - getPosition(): Point { + getPosition(): PositionType { return this._position; } @@ -167,7 +165,7 @@ class DragTopic { return true; } - applyChanges(workspace: Workspace) { + applyChanges(workspace: Canvas) { $assert(workspace, 'workspace can not be null'); const actionDispatcher = ActionDispatcher.getInstance(); @@ -205,9 +203,9 @@ class DragTopic { return false; } - static init(workspace: Workspace) { + static init(workspace: Canvas) { $assert(workspace, 'workspace can not be null'); - const pivot = DragTopic._dragPivot; + const pivot: CanvasElement = DragTopic._dragPivot; workspace.append(pivot); } } diff --git a/packages/mindplot/src/components/EmojiCharIcon.ts b/packages/mindplot/src/components/EmojiCharIcon.ts index e90d79a9..691aa375 100644 --- a/packages/mindplot/src/components/EmojiCharIcon.ts +++ b/packages/mindplot/src/components/EmojiCharIcon.ts @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Text, Group, ElementClass, Point } from '@wisemapping/web2d'; +import { Text, Group } from '@wisemapping/web2d'; import Icon from './Icon'; import IconGroup from './IconGroup'; @@ -23,11 +23,12 @@ import SvgIconModel from './model/SvgIconModel'; import SizeType from './SizeType'; import Topic from './Topic'; import ActionDispatcher from './ActionDispatcher'; +import PositionType from './PositionType'; class EmojiCharIcon implements Icon { - private element: ElementClass; + private _group: Group; - private _group: IconGroup | null; + private _iconGroup: IconGroup | null; private _iconModel: SvgIconModel; @@ -37,48 +38,48 @@ class EmojiCharIcon implements Icon { this._iconModel = iconModel; this._topic = topic; - this.element = new Group({ - width: 90, - height: 90, + this._group = new Group({ + width: 70, + height: 70, x: 0, y: 0, coordSizeWidth: 15, coordSizeHeight: 15, - coordOriginY: 2, + coordOriginY: 0, }); const iconText = new Text(); iconText.setText(iconModel.getIconType()); - this.element.append(iconText); + this._group.append(iconText); // Add events ... if (!readOnly) { - this.element.setCursor('pointer'); + this._group.setCursor('pointer'); } - this._group = null; + this._iconGroup = null; } - getElement(): ElementClass { - return this.element; + getElement(): Group { + return this._group; } setGroup(group: IconGroup) { - this._group = group; + this._iconGroup = group; } getGroup(): IconGroup { - return this._group!; + return this._iconGroup!; } getSize(): SizeType { - return this._group!.getSize(); + return this._iconGroup!.getSize(); } - getPosition(): Point { - return this._group!.getPosition(); + getPosition(): PositionType { + return this._iconGroup!.getPosition(); } addEvent(type: string, fnc: (e: object) => void): void { - this.element.addEvent(type, fnc); + this._group.addEvent(type, fnc); } remove() { diff --git a/packages/mindplot/src/components/Icon.ts b/packages/mindplot/src/components/Icon.ts index 4de70fe2..5a053774 100644 --- a/packages/mindplot/src/components/Icon.ts +++ b/packages/mindplot/src/components/Icon.ts @@ -1,18 +1,36 @@ -import { Point, ElementClass, Group } from '@wisemapping/web2d'; +/* + * Copyright [2021] [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. + */ +import { Group, Image } from '@wisemapping/web2d'; import IconGroup from './IconGroup'; import FeatureModel from './model/FeatureModel'; +import PositionType from './PositionType'; import SizeType from './SizeType'; interface Icon { - getElement(): ElementClass; + getElement(): Group | Image; - setGroup(group: IconGroup): Group; + setGroup(group: IconGroup): void; getGroup(): IconGroup | null; - getSize(): SizeType; + getSize(): SizeType | undefined; - getPosition(): Point; + getPosition(): PositionType; addEvent(type: string, fnc: () => void): void; diff --git a/packages/mindplot/src/components/IconGroup.ts b/packages/mindplot/src/components/IconGroup.ts index b7da90e3..99f33050 100644 --- a/packages/mindplot/src/components/IconGroup.ts +++ b/packages/mindplot/src/components/IconGroup.ts @@ -16,13 +16,14 @@ * limitations under the License. */ -import { $assert, $defined } from '@wisemapping/core-js'; -import { Group, ElementClass, Point } from '@wisemapping/web2d'; +import { $assert } from '@wisemapping/core-js'; +import { Group } from '@wisemapping/web2d'; import IconGroupRemoveTip from './IconGroupRemoveTip'; import ImageIcon from './ImageIcon'; import SizeType from './SizeType'; import FeatureModel from './model/FeatureModel'; import Icon from './Icon'; +import PositionType from './PositionType'; const ORDER_BY_TYPE = new Map(); ORDER_BY_TYPE.set('icon', 0); @@ -61,14 +62,10 @@ class IconGroup { this._group.setPosition(x, y); } - getPosition(): Point { + getPosition(): PositionType { return this._group.getPosition(); } - getNativeElement(): ElementClass { - return this._group; - } - /** */ getSize(): SizeType { return this._group.getSize(); @@ -84,8 +81,6 @@ class IconGroup { } addIcon(icon: Icon, remove: boolean): void { - $defined(icon, 'icon is not defined'); - // Order could have change, need to re-add all. const icons = this._icons.slice(); this._icons.forEach((i) => { @@ -102,7 +97,7 @@ class IconGroup { // Add all the nodes back ... this._resize(this._icons.length); this._icons.forEach((i, index) => { - this._positionIcon(i, index); + this.positionIcon(i, index); const imageShape = i.getElement(); this._group.append(imageShape); }); @@ -132,14 +127,14 @@ class IconGroup { } /** */ - removeIconByModel(featureModel: FeatureModel) { + removeIconByModel(featureModel: FeatureModel): void { $assert(featureModel, 'featureModel can not be null'); const icon = this._findIconFromModel(featureModel); this._removeIcon(icon); } - private _removeIcon(icon: Icon) { + private _removeIcon(icon: Icon): void { this._removeTip.close(0); this._group.removeChild(icon.getElement()); @@ -149,7 +144,7 @@ class IconGroup { // Add all again ... this._icons.forEach((elem, i) => { - me._positionIcon(elem, i); + me.positionIcon(elem, i); }); } @@ -169,7 +164,7 @@ class IconGroup { }); } - private _resize(iconsLength: number) { + private _resize(iconsLength: number): void { if (this._iconSize) { this._group.setSize(iconsLength * this._iconSize.width, this._iconSize.height); @@ -178,14 +173,19 @@ class IconGroup { } } - private _positionIcon(icon: Icon, order: number) { + private positionIcon(icon: Icon, order: number): void { const iconSize = ImageIcon.SIZE + IconGroup.ICON_PADDING * 2; icon .getElement() .setPosition(iconSize * order + IconGroup.ICON_PADDING, IconGroup.ICON_PADDING); } - static ICON_PADDING = 5; + appendTo(group: Group): void { + group.append(this._group); + this._group.moveToFront(); + } + + static ICON_PADDING = 2; } export default IconGroup; diff --git a/packages/mindplot/src/components/IconGroupRemoveTip.ts b/packages/mindplot/src/components/IconGroupRemoveTip.ts index 7ec2332a..53ff50d3 100644 --- a/packages/mindplot/src/components/IconGroupRemoveTip.ts +++ b/packages/mindplot/src/components/IconGroupRemoveTip.ts @@ -7,7 +7,7 @@ class IconGroupRemoveTip { private _activeIcon: ImageIcon | null; - private _widget: Group; + private _widget: Group | null; private _closeTimeoutId; @@ -15,6 +15,7 @@ class IconGroupRemoveTip { $assert(group, 'group can not be null'); this._group = group; this._activeIcon = null; + this._widget = null; } show(topicId: number, icon: ImageIcon) { @@ -71,7 +72,9 @@ class IconGroupRemoveTip { const close = () => { this._activeIcon = null; - this._group.removeChild(widget); + if (widget) { + this._group.removeChild(widget); + } this._widget = null; this._closeTimeoutId = null; }; diff --git a/packages/mindplot/src/components/ImageIcon.ts b/packages/mindplot/src/components/ImageIcon.ts index 334072f0..f8c99b6d 100644 --- a/packages/mindplot/src/components/ImageIcon.ts +++ b/packages/mindplot/src/components/ImageIcon.ts @@ -16,11 +16,12 @@ * limitations under the License. */ import { $assert } from '@wisemapping/core-js'; -import { Image, Point, ElementClass } from '@wisemapping/web2d'; +import { Group, Image } from '@wisemapping/web2d'; import IconGroup from './IconGroup'; import SizeType from './SizeType'; import FeatureModel from './model/FeatureModel'; import Icon from './Icon'; +import PositionType from './PositionType'; abstract class ImageIcon implements Icon { private _image: Image; @@ -35,11 +36,11 @@ abstract class ImageIcon implements Icon { this._group = null; } - getElement(): ElementClass { + getElement(): Image | Group { return this._image; } - setGroup(group: IconGroup) { + setGroup(group: IconGroup): void { this._group = group; } @@ -47,11 +48,11 @@ abstract class ImageIcon implements Icon { return this._group; } - getSize(): SizeType { + getSize(): SizeType | undefined { return this._image.getSize(); } - getPosition(): Point { + getPosition(): PositionType { return this._image.getPosition(); } diff --git a/packages/mindplot/src/components/Keyboard.ts b/packages/mindplot/src/components/Keyboard.ts index 9d581b39..3c4f2737 100644 --- a/packages/mindplot/src/components/Keyboard.ts +++ b/packages/mindplot/src/components/Keyboard.ts @@ -16,7 +16,7 @@ * limitations under the License. */ import $ from 'jquery'; -import initHotKeyPluggin from '../../../../libraries/jquery.hotkeys'; +import initHotKeyPluggin from '../../libraries/jquery.hotkeys'; // Provides dispatcher of keyevents by key... initHotKeyPluggin($); diff --git a/packages/mindplot/src/components/MainTopic.ts b/packages/mindplot/src/components/MainTopic.ts index 84d09004..8db16d63 100644 --- a/packages/mindplot/src/components/MainTopic.ts +++ b/packages/mindplot/src/components/MainTopic.ts @@ -16,12 +16,12 @@ * limitations under the License. */ import { $assert, $defined } from '@wisemapping/core-js'; -import { Point, Group, ElementClass } from '@wisemapping/web2d'; +import { Group, ElementClass, ElementPeer } from '@wisemapping/web2d'; import Topic from './Topic'; import Shape from './util/Shape'; import NodeModel from './model/NodeModel'; -import Workspace from './Workspace'; +import Canvas from './Canvas'; import SizeType from './SizeType'; import PositionType from './PositionType'; import { NodeOption } from './NodeGraph'; @@ -34,7 +34,7 @@ class MainTopic extends Topic { this.INNER_RECT_ATTRIBUTES = { stroke: '0.5 solid #009900' }; } - _buildDragShape(): ElementClass { + buildDragShape(): ElementClass { const innerShape = this._buildShape(this.INNER_RECT_ATTRIBUTES, this.getShapeType()); const size = this.getSize(); innerShape.setSize(size.width, size.height); @@ -82,9 +82,8 @@ class MainTopic extends Topic { } } - disconnect(workspace: Workspace) { + disconnect(workspace: Canvas) { super.disconnect(workspace); - this.redrawShapeType(); const innerShape = this.getInnerShape(); innerShape.setVisibility(true); @@ -113,7 +112,7 @@ class MainTopic extends Topic { const isAtRight = Shape.isAtRight(targetPosition, pos); const size = this.getSize(); - let result: Point = { x: 0, y: 0 }; + let result: PositionType = { x: 0, y: 0 }; if (this.getShapeType() === 'line') { const groupPosition = this.get2DElement().getPosition(); const innerShareSize = this.getInnerShape().getSize(); diff --git a/packages/mindplot/src/components/MultilineTextEditor.ts b/packages/mindplot/src/components/MultilineTextEditor.ts index 5c677fc5..c8c1bca7 100644 --- a/packages/mindplot/src/components/MultilineTextEditor.ts +++ b/packages/mindplot/src/components/MultilineTextEditor.ts @@ -16,13 +16,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { $defined } from '@wisemapping/core-js'; +import { FontStyle } from '@wisemapping/web2d/src/components/peer/svg/FontPeer'; import $ from 'jquery'; import ActionDispatcher from './ActionDispatcher'; import Events from './Events'; -import { FontStyleType } from './FontStyleType'; -import { FontWeightType } from './FontWeightType'; import EventBus from './layout/EventBus'; import Topic from './Topic'; @@ -98,32 +96,29 @@ class EditorComponent extends Events { event.stopPropagation(); }); - textareaElem.on('keypress', (event) => { - event.stopPropagation(); - }); - - textareaElem.on('keyup', (event) => { - const text = this.getTextareaElem().val(); - - this._topic.setText(text?.toString()); - this.resize(); + textareaElem.on('keypress', (event: JQuery.Event) => { + const c = String.fromCharCode(event.which!); + const text = this.getTextareaElem().val() + c; + this._topic.setText(text); + this.resize(text); this.fireEvent('input', [event, text]); + event.stopPropagation(); }); // If the user clicks on the input, all event must be ignored ... - containerElem.on('click', (event) => { + containerElem.on('click', (event: JQuery.Event) => { event.stopPropagation(); }); - containerElem.on('dblclick', (event) => { + containerElem.on('dblclick', (event: JQuery.Event) => { event.stopPropagation(); }); - containerElem.on('mousedown', (event) => { + containerElem.on('mousedown', (event: JQuery.Event) => { event.stopPropagation(); }); } - private resize() { + private resize(text?: string) { // Force relayout ... EventBus.instance.fireEvent('forceLayout'); @@ -132,8 +127,9 @@ class EditorComponent extends Events { const { top, left } = textShape.getNativePosition(); this._containerElem.offset({ top, left }); + const textValue = text || this.getTextAreaText(); const textElem = this.getTextareaElem(); - const lines = this.getTextAreaText().split('\n'); + const lines = textValue.split('\n'); let maxLineLength = 1; lines.forEach((line: string) => { @@ -175,6 +171,7 @@ class EditorComponent extends Events { const fontStyle = nodeText.getFontStyle(); fontStyle.size = nodeText.getHtmlFontSize(); fontStyle.color = nodeText.getColor(); + this.setStyle(fontStyle); // Set editor's initial size @@ -192,17 +189,9 @@ class EditorComponent extends Events { this.positionCursor(textAreaElem, textOverwrite === undefined); } textAreaElem.trigger('focus'); - - this.resize(); } - private setStyle(fontStyle: { - fontFamily: string; - style: FontStyleType; - weight: FontWeightType; - size: number; - color: string; - }) { + private setStyle(fontStyle: FontStyle) { const inputField = this.getTextareaElem(); // allowed param reassign to avoid risks of existing code relying in this side-effect if (!fontStyle.fontFamily) { @@ -214,25 +203,26 @@ class EditorComponent extends Events { if (!fontStyle.weight) { fontStyle.weight = 'normal'; } - if (!$defined(fontStyle.size)) { - fontStyle.size = 12; - } + /* eslint-enable no-param-reassign */ - const style = { - fontSize: `${fontStyle.size}px`, - fontFamily: fontStyle.fontFamily, - fontStyle: fontStyle.style, - fontWeight: fontStyle.weight, - color: fontStyle.color, + const cssStyle = { + 'font-size': `${fontStyle.size}px`, + 'font-family': fontStyle.fontFamily, + 'font-style': fontStyle.style, + 'font-weight': fontStyle.weight, + color: fontStyle.color!, }; - inputField.css(style); - this._containerElem.css(style); + inputField.css(cssStyle); + this._containerElem.css(cssStyle); } private setText(text: string): void { const textareaElem = this.getTextareaElem(); textareaElem.val(text); - this.resize(); + + this._topic.setText(text); + + this.resize(text); } private getTextAreaText(): string { diff --git a/packages/mindplot/src/components/NodeGraph.ts b/packages/mindplot/src/components/NodeGraph.ts index beb95ac8..a32fd9f9 100644 --- a/packages/mindplot/src/components/NodeGraph.ts +++ b/packages/mindplot/src/components/NodeGraph.ts @@ -15,19 +15,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { ElementClass, ElementPeer, Group } from '@wisemapping/web2d'; import { $assert } from '@wisemapping/core-js'; -import { ElementClass, Point } from '@wisemapping/web2d'; import NodeModel from './model/NodeModel'; -import Workspace from './Workspace'; +import Canvas from './Canvas'; import DragTopic from './DragTopic'; import LayoutManager from './layout/LayoutManager'; import SizeType from './SizeType'; +import PositionType from './PositionType'; +import CanvasElement from './CanvasElement'; export type NodeOption = { readOnly: boolean; }; -abstract class NodeGraph { +abstract class NodeGraph implements CanvasElement { private _mouseEvents: boolean; private _options: NodeOption; @@ -38,7 +40,7 @@ abstract class NodeGraph { private _model: NodeModel; - private _elem2d: ElementClass; + private _elem2d: Group | undefined; constructor(nodeModel: NodeModel, options: NodeOption) { $assert(nodeModel, 'model can not be null'); @@ -50,6 +52,10 @@ abstract class NodeGraph { this._size = { width: 50, height: 20 }; } + abstract addToWorkspace(workspace: Canvas): void; + + abstract removeFromWorkspace(workspace: Canvas): void; + isReadOnly(): boolean { return this._options.readOnly; } @@ -64,15 +70,18 @@ abstract class NodeGraph { this.getModel().setId(id); } - protected _set2DElement(elem2d: ElementClass) { + protected _set2DElement(elem2d: Group) { this._elem2d = elem2d; } - get2DElement(): ElementClass { + get2DElement(): Group { + if (!this._elem2d) { + throw new Error('Eleemnt has not been initialized.'); + } return this._elem2d; } - abstract setPosition(point, fireEvent): void; + abstract setPosition(point: PositionType, fireEvent): void; /** */ addEvent(type: string, listener) { @@ -81,13 +90,13 @@ abstract class NodeGraph { } /** */ - removeEvent(type, listener) { + removeEvent(type: string, listener) { const elem = this.get2DElement(); elem.removeEvent(type, listener); } /** */ - fireEvent(type, event) { + fireEvent(type: string, event) { const elem = this.get2DElement(); elem.trigger(type, event); } @@ -131,26 +140,26 @@ abstract class NodeGraph { abstract setCursor(type: string): void; - abstract getOuterShape(): ElementClass; + abstract getOuterShape(): ElementClass; isOnFocus(): boolean { return this._onFocus; } - dispose(workspace: Workspace) { + dispose(workspace: Canvas) { this.setOnFocus(false); workspace.removeChild(this); } createDragNode(layoutManager: LayoutManager): DragTopic { - const dragShape = this._buildDragShape(); + const dragShape = this.buildDragShape(); return new DragTopic(dragShape, this, layoutManager); } - abstract _buildDragShape(); + abstract buildDragShape(); - getPosition(): Point { + getPosition(): PositionType { const model = this.getModel(); return model.getPosition(); } diff --git a/packages/mindplot/src/components/Relationship.ts b/packages/mindplot/src/components/Relationship.ts index 08cd4fcd..e4859ac6 100644 --- a/packages/mindplot/src/components/Relationship.ts +++ b/packages/mindplot/src/components/Relationship.ts @@ -15,18 +15,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { $assert, $defined } from '@wisemapping/core-js'; -import { Arrow, Point, CurvedLine } from '@wisemapping/web2d'; +import { Arrow, Line } from '@wisemapping/web2d'; import ConnectionLine, { LineType } from './ConnectionLine'; import RelationshipControlPoints from './RelationshipControlPoints'; import RelationshipModel from './model/RelationshipModel'; import PositionType from './PositionType'; import Topic from './Topic'; import Shape from './util/Shape'; -import Workspace from './Workspace'; +import Canvas from './Canvas'; class Relationship extends ConnectionLine { - private _focusShape: CurvedLine; + private _focusShape: Line; private _onFocus: boolean; @@ -34,16 +33,16 @@ class Relationship extends ConnectionLine { private _controlPointsController: RelationshipControlPoints; + private _showStartArrow: boolean; + + private _showEndArrow: boolean; + + private _endArrow!: Arrow; + private _startArrow: Arrow; - private _showEndArrow: Arrow; - - private _endArrow: Arrow; - private _onFocusHandler: (event: MouseEvent) => void; - private _showStartArrow: Arrow; - private _model: RelationshipModel; constructor(sourceNode: Topic, targetNode: Topic, model: RelationshipModel) { @@ -70,6 +69,8 @@ class Relationship extends ConnectionLine { this._focusShape.setOpacity(0); this._focusShape.setFill('none', 1); this._focusShape.setCursor('pointer'); + this._showStartArrow = false; + this._showEndArrow = false; // Build arrow ... this._startArrow = new Arrow(); @@ -89,12 +90,12 @@ class Relationship extends ConnectionLine { // Position the line ... if (model.getSrcCtrlPoint()) { - const srcPoint = { ...model.getSrcCtrlPoint() }; + const srcPoint = { ...model.getSrcCtrlPoint()! }; this.setSrcControlPoint(srcPoint); } if (model.getDestCtrlPoint()) { - const destPoint = { ...model.getDestCtrlPoint() }; + const destPoint = { ...model.getDestCtrlPoint()! }; this.setDestControlPoint(destPoint); } @@ -113,7 +114,7 @@ class Relationship extends ConnectionLine { setStroke(color: string, style: string, opacity: number): void { super.setStroke(color, style, opacity); - this._startArrow.setStrokeColor(color); + this._startArrow?.setStrokeColor(color); } getModel(): RelationshipModel { @@ -132,7 +133,7 @@ class Relationship extends ConnectionLine { } this._line.setStroke(2); - let ctrlPoints: [Point, Point]; + let ctrlPoints: [PositionType, PositionType]; // Position line ... if (!line2d.isDestControlPointCustom() && !line2d.isSrcControlPointCustom()) { @@ -147,14 +148,14 @@ class Relationship extends ConnectionLine { const tpointX = ctrlPoints[1].x + tPos.x; const tpointY = ctrlPoints[1].y + tPos.y; - const nsPos = Shape.calculateRelationShipPointCoordinates( - sourceTopic, - new Point(spointX, spointY), - ); - const ntPos = Shape.calculateRelationShipPointCoordinates( - targetTopic, - new Point(tpointX, tpointY), - ); + const nsPos = Shape.calculateRelationShipPointCoordinates(sourceTopic, { + x: spointX, + y: spointY, + }); + const ntPos = Shape.calculateRelationShipPointCoordinates(targetTopic, { + x: tpointX, + y: tpointY, + }); line2d.setFrom(nsPos.x, nsPos.y); line2d.setTo(ntPos.x, ntPos.y); @@ -210,10 +211,10 @@ class Relationship extends ConnectionLine { } } - addToWorkspace(workspace: Workspace): void { + addToWorkspace(workspace: Canvas): void { this.updatePositions(); - workspace.append(this._focusShape); + workspace.append(this._focusShape.getElementClass()); workspace.append(this._controlPointsController); if (workspace.isReadOnly()) { @@ -232,8 +233,8 @@ class Relationship extends ConnectionLine { this.redraw(); } - removeFromWorkspace(workspace: Workspace): void { - workspace.removeChild(this._focusShape); + removeFromWorkspace(workspace: Canvas): void { + workspace.removeChild(this._focusShape.getElementClass()); workspace.removeChild(this._controlPointsController); this._line.removeEvent('click', this._onFocusHandler); @@ -337,17 +338,11 @@ class Relationship extends ConnectionLine { } setFrom(x: number, y: number): void { - $assert($defined(x), 'x must be defined'); - $assert($defined(y), 'y must be defined'); - this._line.setFrom(x, y); - this._startArrow.setFrom(x, y); + this._startArrow?.setFrom(x, y); } setTo(x: number, y: number) { - $assert($defined(x), 'x must be defined'); - $assert($defined(y), 'y must be defined'); - this._line.setTo(x, y); if (this._endArrow) this._endArrow.setFrom(x, y); } @@ -355,18 +350,18 @@ class Relationship extends ConnectionLine { setSrcControlPoint(control: PositionType): void { this._line.setSrcControlPoint(control); this._focusShape.setSrcControlPoint(control); - this._startArrow.setControlPoint(control); + this._startArrow?.setControlPoint(control); } setDestControlPoint(control: PositionType) { this._line.setDestControlPoint(control); this._focusShape.setSrcControlPoint(control); if (this._showEndArrow) { - this._endArrow.setControlPoint(control); + this._endArrow?.setControlPoint(control); } } - getControlPoints(): PositionType { + getControlPoints(): [PositionType, PositionType] { return this._line.getControlPoints(); } diff --git a/packages/mindplot/src/components/RelationshipControlPoints.ts b/packages/mindplot/src/components/RelationshipControlPoints.ts index d336bbe1..380f46e9 100644 --- a/packages/mindplot/src/components/RelationshipControlPoints.ts +++ b/packages/mindplot/src/components/RelationshipControlPoints.ts @@ -19,7 +19,7 @@ import { Elipse, StraightLine } from '@wisemapping/web2d'; import Shape from './util/Shape'; import ActionDispatcher from './ActionDispatcher'; -import Workspace from './Workspace'; +import Canvas from './Canvas'; import PositionType from './PositionType'; import Relationship from './Relationship'; @@ -36,7 +36,7 @@ class ControlPivotLine { private _pivotType: PivotType; - private _workspace: Workspace | null; + private _canvas: Canvas | null; private _relationship: Relationship; @@ -95,7 +95,7 @@ class ControlPivotLine { this._mouseDownHandler = (event: MouseEvent) => this.mouseDownHandler(event); this._isVisible = false; - this._workspace = null; + this._canvas = null; } private mouseDownHandler(event: MouseEvent) { @@ -156,7 +156,7 @@ class ControlPivotLine { } private mouseMoveHandler(event: MouseEvent) { - const screen = this._workspace!.getScreenManager(); + const screen = this._canvas!.getScreenManager(); const mousePosition = screen.getWorkspaceMousePosition(event); // Update relatioship position ... @@ -189,14 +189,14 @@ class ControlPivotLine { this._changeHander(); } - addToWorkspace(workspace: Workspace): void { - this._workspace = workspace; + addToWorkspace(workspace: Canvas): void { + this._canvas = workspace; workspace.append(this._line); workspace.append(this._dot); } - removeFromWorkspace(workspace: Workspace) { + removeFromWorkspace(workspace: Canvas) { // Hide all elements ... this.setVisibility(false); @@ -205,8 +205,8 @@ class ControlPivotLine { workspace.removeChild(this._dot); } - private getWorkspace(): Workspace { - return this._workspace!; + private getWorkspace(): Canvas { + return this._canvas!; } } @@ -256,11 +256,11 @@ class RelationshipControlPoints { this._pivotLines = [startControlLine, endControlLine]; } - addToWorkspace(workspace: Workspace): void { + addToWorkspace(workspace: Canvas): void { this._pivotLines.forEach((pivot) => workspace.append(pivot)); } - removeFromWorkspace(workspace: Workspace) { + removeFromWorkspace(workspace: Canvas) { this._pivotLines.forEach((pivot) => workspace.removeChild(pivot)); } diff --git a/packages/mindplot/src/components/RelationshipPivot.ts b/packages/mindplot/src/components/RelationshipPivot.ts index b36793fd..a71b01ff 100644 --- a/packages/mindplot/src/components/RelationshipPivot.ts +++ b/packages/mindplot/src/components/RelationshipPivot.ts @@ -15,16 +15,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { CurvedLine, Arrow, Point } from '@wisemapping/web2d'; -import { $assert } from '@wisemapping/core-js'; +import { CurvedLine, Arrow } from '@wisemapping/web2d'; import Relationship from './Relationship'; import Shape from './util/Shape'; -import Workspace from './Workspace'; +import Canvas from './Canvas'; import { Designer } from '..'; import Topic from './Topic'; +import PositionType from './PositionType'; class RelationshipPivot { - private _workspace: Workspace; + private _canvas: Canvas; private _designer: Designer; @@ -36,29 +36,26 @@ class RelationshipPivot { private _sourceTopic: Topic | null; - private _pivot: CurvedLine; + private _pivot: CurvedLine | null; - private _startArrow: Arrow; + private _startArrow: Arrow | null; - constructor(workspace: Workspace, designer: Designer) { - $assert(workspace, 'workspace can not be null'); - $assert(designer, 'designer can not be null'); - this._workspace = workspace; + constructor(canvas: Canvas, designer: Designer) { + this._canvas = canvas; this._designer = designer; this._mouseMoveEvent = this.mouseMoveHandler.bind(this); this._onClickEvent = this.cleanOnMouseClick.bind(this); this._onTopicClick = this._connectOnFocus.bind(this); this._sourceTopic = null; + this._pivot = null; + this._startArrow = null; } - start(sourceTopic: Topic, targetPos: Point) { - $assert(sourceTopic, 'sourceTopic can not be null'); - $assert(targetPos, 'targetPos can not be null'); - + start(sourceTopic: Topic, targetPos: PositionType): void { this.dispose(); this._sourceTopic = sourceTopic; - this._workspace.enableWorkspaceEvents(false); + this._canvas.enableWorkspaceEvents(false); const sourcePos = sourceTopic.getPosition(); const strokeColor = Relationship.getStrokeColor(); @@ -76,11 +73,11 @@ class RelationshipPivot { this._startArrow.setStrokeWidth(2); this._startArrow.setFrom(sourcePos.x, sourcePos.y); - this._workspace.append(this._pivot); - this._workspace.append(this._startArrow); + this._canvas.append(this._pivot); + this._canvas.append(this._startArrow); - this._workspace.addEvent('mousemove', this._mouseMoveEvent); - this._workspace.addEvent('click', this._onClickEvent); + this._canvas.addEvent('mousemove', this._mouseMoveEvent); + this._canvas.addEvent('click', this._onClickEvent); // Register focus events on all topics ... const model = this._designer.getModel(); @@ -91,7 +88,7 @@ class RelationshipPivot { } dispose(): void { - const workspace = this._workspace; + const workspace = this._canvas; if (this._isActive()) { workspace.removeEvent('mousemove', this._mouseMoveEvent); @@ -104,8 +101,12 @@ class RelationshipPivot { topic.removeEvent('ontfocus', this._onTopicClick); }); - workspace.removeChild(this._pivot); - workspace.removeChild(this._startArrow); + if (this._pivot) { + workspace.removeChild(this._pivot); + } + if (this._startArrow) { + workspace.removeChild(this._startArrow); + } workspace.enableWorkspaceEvents(true); this._sourceTopic = null; @@ -115,7 +116,7 @@ class RelationshipPivot { } private mouseMoveHandler(event: MouseEvent): boolean { - const screen = this._workspace.getScreenManager(); + const screen = this._canvas.getScreenManager(); const pos = screen.getWorkspaceMousePosition(event); // Leave the arrow a couple of pixels away from the cursor. @@ -123,14 +124,14 @@ class RelationshipPivot { const gapDistance = Math.sign(pos.x - sourcePosition.x) * 5; const sPos = this._calculateFromPosition(pos); - this._pivot.setFrom(sPos.x, sPos.y); + this._pivot!.setFrom(sPos.x, sPos.y); // Update target position ... - this._pivot.setTo(pos.x - gapDistance, pos.y); + 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]); + const controlPoints = this._pivot!.getControlPoints(); + this._startArrow!.setFrom(pos.x - gapDistance, pos.y); + this._startArrow!.setControlPoint(controlPoints[1]); event.stopPropagation(); return false; @@ -142,7 +143,7 @@ class RelationshipPivot { event.stopPropagation(); } - private _calculateFromPosition(toPosition: Point): Point { + private _calculateFromPosition(toPosition: PositionType): PositionType { // Calculate origin position ... const sourceTopic = this._sourceTopic!; let sourcePosition = this._sourceTopic!.getPosition(); diff --git a/packages/mindplot/src/components/ScreenManager.ts b/packages/mindplot/src/components/ScreenManager.ts index 89196f7f..fd249d8a 100644 --- a/packages/mindplot/src/components/ScreenManager.ts +++ b/packages/mindplot/src/components/ScreenManager.ts @@ -17,11 +17,11 @@ */ import $ from 'jquery'; import { $assert } from '@wisemapping/core-js'; -import { Point } from '@wisemapping/web2d'; // https://stackoverflow.com/questions/60357083/does-not-use-passive-listeners-to-improve-scrolling-performance-lighthouse-repo // https://web.dev/uses-passive-event-listeners/?utm_source=lighthouse&utm_medium=lr // eslint-disable-next-line import/extensions -import registerTouchHandler from '../../../../libraries/jquery.touchevent'; +import registerTouchHandler from '../../libraries/jquery.touchevent'; +import PositionType from './PositionType'; registerTouchHandler($); @@ -99,7 +99,7 @@ class ScreenManager { private tocuchEvents = ['touchstart', 'touchend', 'touchmove']; - getWorkspaceMousePosition(event: MouseEvent | TouchEvent): Point { + getWorkspaceMousePosition(event: MouseEvent | TouchEvent): PositionType { let x: number | null = null; let y: number | null = null; @@ -131,10 +131,10 @@ class ScreenManager { y += this._padding.y; // Remove decimal part.. - return new Point(x, y); + return { x, y }; } - getContainer(): JQuery { + getContainer(): JQuery { return this._divContainer; } diff --git a/packages/mindplot/src/components/ShrinkConnector.ts b/packages/mindplot/src/components/ShrinkConnector.ts index aad05a6d..6d0fa489 100644 --- a/packages/mindplot/src/components/ShrinkConnector.ts +++ b/packages/mindplot/src/components/ShrinkConnector.ts @@ -71,15 +71,15 @@ class ShirinkConnector { changeRender(isShrink: boolean) { const elipse = this._ellipse; if (isShrink) { - elipse.setStroke('2', 'solid'); + elipse.setStroke(2, 'solid'); } else { - elipse.setStroke('1', 'solid'); + elipse.setStroke(1, 'solid'); } this._isShrink = isShrink; } setColor(color: string) { - this._ellipse.setStroke('1', 'solid', color); + this._ellipse.setStroke(1, 'solid', color); this._ellipse.setFill(ColorUtil.lightenColor(color, 100)); } diff --git a/packages/mindplot/src/components/StandaloneActionDispatcher.ts b/packages/mindplot/src/components/StandaloneActionDispatcher.ts index a576657a..5d1e1702 100644 --- a/packages/mindplot/src/components/StandaloneActionDispatcher.ts +++ b/packages/mindplot/src/components/StandaloneActionDispatcher.ts @@ -16,7 +16,6 @@ * limitations under the License. */ import { $defined, $assert } from '@wisemapping/core-js'; -import { Point } from '@wisemapping/web2d'; import ActionDispatcher from './ActionDispatcher'; import DesignerActionRunner from './DesignerActionRunner'; import AddTopicCommand from './commands/AddTopicCommand'; @@ -73,17 +72,17 @@ class StandaloneActionDispatcher extends ActionDispatcher { } /** */ - dragTopic(topicId: number, position: Point, order: number, parentTopic: Topic) { + dragTopic(topicId: number, position: PositionType, order: number, parentTopic: Topic): void { const command = new DragTopicCommand(topicId, position, order, parentTopic); this.execute(command); } /** */ - moveTopic(topicId: number, position: Point) { + moveTopic(topicId: number, position: PositionType): void { $assert($defined(topicId), 'topicsId can not be null'); $assert($defined(position), 'position can not be null'); - const commandFunc = (topic: Topic, pos: Point) => { + const commandFunc = (topic: Topic, pos: PositionType) => { const result = topic.getPosition(); EventBus.instance.fireEvent('topicMoved', { node: topic.getModel(), diff --git a/packages/mindplot/src/components/SvgImageIcon.ts b/packages/mindplot/src/components/SvgImageIcon.ts index 5483f868..5f7131a3 100644 --- a/packages/mindplot/src/components/SvgImageIcon.ts +++ b/packages/mindplot/src/components/SvgImageIcon.ts @@ -16,6 +16,8 @@ * limitations under the License. */ import { $assert } from '@wisemapping/core-js'; +import { Image } from '@wisemapping/web2d'; + import ImageIcon from './ImageIcon'; import ActionDispatcher from './ActionDispatcher'; import iconFamily from './model/SvgIconFamily.json'; @@ -54,13 +56,13 @@ class SvgImageIcon extends ImageIcon { if (!readOnly) { // Icon const image = this.getElement(); - const me = this; image.addEvent('click', () => { const iconTypeClick = iconModel.getIconType(); const newIconType = SvgImageIcon._getNextFamilyIconId(iconTypeClick); iconModel.setIconType(newIconType); - me.getElement().setHref(SvgImageIcon.getImageUrl(newIconType)); + const url = SvgImageIcon.getImageUrl(newIconType); + (this.getElement() as Image).setHref(url); }); this.getElement().setCursor('pointer'); } diff --git a/packages/mindplot/src/components/Topic.ts b/packages/mindplot/src/components/Topic.ts index 1d707ae6..c790902c 100644 --- a/packages/mindplot/src/components/Topic.ts +++ b/packages/mindplot/src/components/Topic.ts @@ -17,7 +17,7 @@ */ import { $assert, $defined } from '@wisemapping/core-js'; -import { Rect, Line, Text, Group, ElementClass } from '@wisemapping/web2d'; +import { Rect, Text, Group, ElementClass, ElementPeer, StyleAttributes } from '@wisemapping/web2d'; import NodeGraph, { NodeOption } from './NodeGraph'; import TopicConfig from './TopicConfig'; @@ -33,7 +33,7 @@ import TopicEventDispatcher, { TopicEvent } from './TopicEventDispatcher'; import { TopicShapeType } from './model/INodeModel'; import NodeModel from './model/NodeModel'; import Relationship from './Relationship'; -import Workspace from './Workspace'; +import Canvas from './Canvas'; import LayoutManager from './layout/LayoutManager'; import NoteModel from './model/NoteModel'; import LinkModel from './model/LinkModel'; @@ -41,7 +41,6 @@ import SizeType from './SizeType'; import FeatureModel from './model/FeatureModel'; import PositionType from './PositionType'; import LineTopicShape from './widget/LineTopicShape'; -import ImageTopicShape from './widget/ImageTopicShape'; import ColorUtil from './render/ColorUtil'; import Icon from './Icon'; import { FontStyleType } from './FontStyleType'; @@ -51,7 +50,7 @@ import DragTopic from './DragTopic'; const ICON_SCALING_FACTOR = 1.3; abstract class Topic extends NodeGraph { - private _innerShape: ElementClass; + private _innerShape: LineTopicShape | Rect | LineTopicShape | null; private _relationships: Relationship[]; @@ -63,9 +62,9 @@ abstract class Topic extends NodeGraph { // eslint-disable-next-line no-use-before-define private _parent: Topic | null; - private _outerShape: ElementClass; + private _outerShape: ElementClass | undefined; - private _text: Text | null; + private _text: Text | undefined; private _iconsGroup!: IconGroup; @@ -79,6 +78,7 @@ abstract class Topic extends NodeGraph { this._parent = null; this._relationships = []; this._isInWorkspace = false; + this._innerShape = null; this._buildTopicShape(); // Position a topic .... @@ -89,11 +89,11 @@ abstract class Topic extends NodeGraph { // Register events for the topic ... if (!this.isReadOnly()) { - this._registerEvents(); + this.registerEvents(); } } - protected _registerEvents(): void { + protected registerEvents(): void { this.setMouseEventsEnabled(true); // Prevent click on the topics being propagated ... @@ -199,15 +199,16 @@ abstract class Topic extends NodeGraph { return result!; } - private _removeInnerShape(): ElementClass { + private _removeInnerShape(): ElementClass { const group = this.get2DElement(); const innerShape = this.getInnerShape(); + group.removeChild(innerShape); this._innerShape = null; return innerShape; } - getInnerShape(): ElementClass { + getInnerShape(): LineTopicShape | Rect | LineTopicShape { if (!this._innerShape) { // Create inner box. this._innerShape = this._buildShape(TopicConfig.INNER_RECT_ATTRIBUTES, this.getShapeType()); @@ -222,8 +223,11 @@ abstract class Topic extends NodeGraph { return this._innerShape; } - protected _buildShape(attributes: object, shapeType: TopicShapeType): ElementClass { - let result: ElementClass; + protected _buildShape( + attributes: StyleAttributes, + shapeType: TopicShapeType, + ): LineTopicShape | Rect | LineTopicShape { + let result: LineTopicShape | Rect | LineTopicShape; switch (shapeType) { case 'rectangle': result = new Rect(0, attributes); @@ -238,7 +242,7 @@ abstract class Topic extends NodeGraph { result = new LineTopicShape(this); break; case 'image': - result = new ImageTopicShape(this); + result = new LineTopicShape(this); break; default: { const exhaustiveCheck: never = shapeType; @@ -260,7 +264,7 @@ abstract class Topic extends NodeGraph { textShape.setCursor(type); } - getOuterShape(): ElementClass { + getOuterShape(): ElementClass { if (!this._outerShape) { const rect = this._buildShape({}, 'rounded rectangle'); @@ -284,13 +288,12 @@ abstract class Topic extends NodeGraph { return this._text; } - private getOrBuildIconGroup(): Group { + private getOrBuildIconGroup(): IconGroup { if (!this._iconsGroup) { const iconGroup = this._buildIconGroup(); const group = this.get2DElement(); - group.append(iconGroup.getNativeElement()); - iconGroup.moveToFront(); + iconGroup.appendTo(group); this._iconsGroup = iconGroup; } return this._iconsGroup; @@ -300,7 +303,7 @@ abstract class Topic extends NodeGraph { return this._iconsGroup; } - private _buildIconGroup(): Group { + private _buildIconGroup(): IconGroup { const textHeight = this.getOrBuildTextShape().getFontHeight(); const iconSize = textHeight * ICON_SCALING_FACTOR; const result = new IconGroup(this.getId(), iconSize); @@ -363,7 +366,7 @@ abstract class Topic extends NodeGraph { this._relationships.push(relationship); } - deleteRelationship(relationship: Rect) { + deleteRelationship(relationship: Relationship) { this._relationships = this._relationships.filter((r) => r !== relationship); } @@ -519,10 +522,12 @@ abstract class Topic extends NodeGraph { getBackgroundColor(): string { const model = this.getModel(); let result = model.getBackgroundColor(); - if (!result && !this.isCentralTopic()) { - const borderColor = this.getBorderColor(); - result = ColorUtil.lightenColor(borderColor, 40); + // Be sure that not overwride default background color ... + const borderColor = model.getBorderColor(); + if (borderColor) { + result = ColorUtil.lightenColor(borderColor, 40); + } } if (!result) { @@ -561,7 +566,7 @@ abstract class Topic extends NodeGraph { return result; } - _buildTopicShape(): ElementClass { + _buildTopicShape(): void { const groupAttributes = { width: 100, height: 100, @@ -596,10 +601,10 @@ abstract class Topic extends NodeGraph { this._registerDefaultListenersToElement(group, this); // Set test id - group.setTestId(model.getId()); + group.setTestId(String(model.getId())); } - private _registerDefaultListenersToElement(elem: ElementClass, topic: Topic) { + private _registerDefaultListenersToElement(elem: ElementClass, topic: Topic) { const mouseOver = function mouseOver() { if (topic.isMouseEventsEnabled()) { topic.handleMouseOver(); @@ -730,7 +735,7 @@ abstract class Topic extends NodeGraph { return result; } - setNoteValue(value: string) { + setNoteValue(value: string): void { const topicId = this.getId(); const model = this.getModel(); const dispatcher = ActionDispatcher.getInstance(); @@ -823,19 +828,19 @@ abstract class Topic extends NodeGraph { } /** */ - getOutgoingLine(): Line { + getOutgoingLine(): ConnectionLine | null { return this._outgoingLine; } - getIncomingLines() { + getIncomingLines(): ConnectionLine[] { const children = this.getChildren(); return children .filter((node) => $defined(node.getOutgoingLine())) - .map((node) => node.getOutgoingLine()); + .map((node) => node.getOutgoingLine()!); } getOutgoingConnectedTopic(): Topic | null { - let result = null; + let result: Topic | null = null; const line = this.getOutgoingLine(); if (line) { result = line.getTargetTopic(); @@ -966,8 +971,9 @@ abstract class Topic extends NodeGraph { const visibility = value ? !model.areChildrenShrunken() : value; children.forEach((child) => { child.setVisibility(visibility, fade); + const outgoingLine = child.getOutgoingLine(); - outgoingLine.setVisibility(visibility); + outgoingLine?.setVisibility(visibility); }); } @@ -993,21 +999,20 @@ abstract class Topic extends NodeGraph { const hasSizeChanged = oldSize.width !== roundedSize.width || oldSize.height !== roundedSize.height; if (hasSizeChanged || force) { - NodeGraph.prototype.setSize.call(this, roundedSize); + super.setSize(size); const outerShape = this.getOuterShape(); const innerShape = this.getInnerShape(); - - outerShape.setSize(roundedSize.width + 6, roundedSize.height + 6); - innerShape.setSize(roundedSize.width, roundedSize.height); + outerShape.setSize(size.width + 6, 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, roundedSize); + this._updatePositionOnChangeSize(oldSize, size); if (hasSizeChanged) { EventBus.instance.fireEvent('topicResize', { node: this.getModel(), - size: roundedSize, + size, }); } } @@ -1015,7 +1020,7 @@ abstract class Topic extends NodeGraph { protected abstract _updatePositionOnChangeSize(oldSize: SizeType, roundedSize: SizeType): void; - disconnect(workspace: Workspace): void { + disconnect(workspace: Canvas): void { const outgoingLine = this.getOutgoingLine(); if (outgoingLine) { $assert(workspace, 'workspace can not be null'); @@ -1039,7 +1044,7 @@ abstract class Topic extends NodeGraph { const connector = targetTopic.getShrinkConnector(); if (connector) { connector.setVisibility(false); - targetTopic.isCollapsed(false); + targetTopic.setChildrenShrunken(true); } } @@ -1062,7 +1067,7 @@ abstract class Topic extends NodeGraph { model.setOrder(value); } - connectTo(targetTopic: Topic, workspace: Workspace): void { + connectTo(targetTopic: Topic, workspace: Canvas): void { // Connect Graphical Nodes ... targetTopic.append(this); this._parent = targetTopic; @@ -1125,18 +1130,18 @@ abstract class Topic extends NodeGraph { return result; } - removeFromWorkspace(workspace: Workspace): void { + removeFromWorkspace(workspace: Canvas): void { const elem2d = this.get2DElement(); workspace.removeChild(elem2d); const line = this.getOutgoingLine(); - if ($defined(line)) { + if (line) { workspace.removeChild(line); } this._isInWorkspace = false; EventBus.instance.fireEvent('topicRemoved', this.getModel()); } - addToWorkspace(workspace: Workspace): void { + addToWorkspace(workspace: Canvas): void { const elem = this.get2DElement(); workspace.append(elem); if (!this.isInWorkspace()) { @@ -1192,6 +1197,7 @@ abstract class Topic extends NodeGraph { const targetTopic = this.getOutgoingConnectedTopic()!; this._outgoingLine = this.createConnectionLine(targetTopic); this._outgoingLine.setVisibility(this.isVisible()); + workspace.append(this._outgoingLine); result = true; } @@ -1211,80 +1217,72 @@ abstract class Topic extends NodeGraph { redraw(redrawChildren = false): void { if (this._isInWorkspace) { const textShape = this.getOrBuildTextShape(); - if (this.getShapeType() !== 'image') { - // Update font ... - const fontColor = this.getFontColor(); - textShape.setColor(fontColor); + // Update font ... + const fontColor = this.getFontColor(); + textShape.setColor(fontColor); - const fontSize = this.getFontSize(); - textShape.setSize(fontSize); + const fontSize = this.getFontSize(); + textShape.setFontSize(fontSize); - const fontWeight = this.getFontWeight(); - textShape.setWeight(fontWeight); + const fontWeight = this.getFontWeight(); + textShape.setWeight(fontWeight); - const fontStyle = this.getFontStyle(); - textShape.setStyle(fontStyle); + const fontStyle = this.getFontStyle(); + textShape.setStyle(fontStyle); - const fontFamily = this.getFontFamily(); - textShape.setFontName(fontFamily); + const fontFamily = this.getFontFamily(); + textShape.setFontName(fontFamily); - const text = this.getText(); - textShape.setText(text.trim()); + const text = this.getText(); + textShape.setText(text.trim()); - // Update other shape style ... - const outerShape = this.getOuterShape(); - const outerFillColor = TopicStyle.defaultOuterBackgroundColor(this, this.isOnFocus()); - const outerBorderColor = TopicStyle.defaultOuterBorderColor(this); + // Update outer shape style ... + const outerShape = this.getOuterShape(); + const outerFillColor = TopicStyle.defaultOuterBackgroundColor(this, this.isOnFocus()); + const outerBorderColor = TopicStyle.defaultOuterBorderColor(this); - outerShape.setFill(outerFillColor); - outerShape.setStroke(1, 'solid', outerBorderColor); + outerShape.setFill(outerFillColor); + outerShape.setStroke(1, 'solid', outerBorderColor); - // Calculate topic size and adjust elements ... - const textWidth = textShape.getWidth(); - const textHeight = textShape.getHeight(); - const padding = TopicStyle.getInnerPadding(this); + // Calculate topic size and adjust elements ... + const textWidth = textShape.getShapeWidth(); + const textHeight = textShape.getShapeHeight(); + const padding = TopicStyle.getInnerPadding(this); - // Adjust icons group based on the font size ... - const iconGroup = this.getOrBuildIconGroup(); - const fontHeight = this.getOrBuildTextShape().getFontHeight(); - const iconHeight = ICON_SCALING_FACTOR * fontHeight; - iconGroup.seIconSize(iconHeight, iconHeight); + // Adjust icons group based on the font size ... + const iconGroup = this.getOrBuildIconGroup(); + const fontHeight = textShape.getFontHeight(); + const iconHeight = ICON_SCALING_FACTOR * fontHeight; + iconGroup.seIconSize(iconHeight, iconHeight); - // Calculate size and adjust ... - const topicHeight = Math.max(iconHeight, textHeight) + padding * 2; - const textIconSpacing = Math.round(fontHeight / 4); - const iconGroupWith = iconGroup.getSize().width; - const topicWith = iconGroupWith + 2 * textIconSpacing + textWidth + padding * 2; + // Calculate size and adjust ... + const topicHeight = textHeight + padding * 2; + const textIconSpacing = fontHeight / 50; + const iconGroupWith = iconGroup.getSize().width; + const topicWith = iconGroupWith + 2 * textIconSpacing + textWidth + padding * 2; - // Update connections ... - const changed = this.redrawConnection(); - this.setSize({ width: topicWith, height: topicHeight }, changed); + // Update connections ... + const changed = this.redrawConnection(); + this.setSize({ width: topicWith, height: topicHeight }, changed); - // Adjust all topic elements positions ... - const yPosition = Math.round((topicHeight - textHeight) / 2); - iconGroup.setPosition(padding, yPosition - yPosition / 10); - textShape.setPosition(padding + iconGroupWith + textIconSpacing, yPosition); + // Adjust all topic elements positions ... + const yPosition = (topicHeight - textHeight) / 2; + iconGroup.setPosition(padding, yPosition - yPosition / 4); + textShape.setPosition(padding + iconGroupWith + textIconSpacing, yPosition); - // Update topic color ... - const borderColor = this.getBorderColor(); - this.getInnerShape().setStroke(1, 'solid', borderColor); + // Update topic color ... + const borderColor = this.getBorderColor(); + this.getInnerShape().setStroke(1, 'solid', borderColor); - const bgColor = this.getBackgroundColor(); - this.getInnerShape().setFill(bgColor); + const bgColor = this.getBackgroundColor(); + this.getInnerShape().setFill(bgColor); - // Force the repaint in case that the main topic color has changed. - if (this.getParent()) { - this._connector!.setColor(borderColor); + // Force the repaint in case that the main topic color has changed. + if (this.getParent()) { + this._connector!.setColor(borderColor); - if (this.getParent()?.isCentralTopic()) { - this._outgoingLine?.redraw(); - } - } - } else { - // In case of images, the size is fixed ... - const size = this.getModel().getImageSize(); - if (size) { - this.setSize(size, false); + if (this.getParent()?.isCentralTopic()) { + this._outgoingLine?.redraw(); } } @@ -1294,13 +1292,15 @@ abstract class Topic extends NodeGraph { } } - private _flatten2DElements(topic: Topic): (Topic | Relationship)[] { - const result: (Topic | Relationship)[] = []; + private _flatten2DElements(topic: Topic): (Topic | Relationship | ConnectionLine)[] { + const result: (Topic | Relationship | ConnectionLine)[] = []; const children = topic.getChildren(); children.forEach((child) => { result.push(child); - result.push(child.getOutgoingLine()); - + const line = child.getOutgoingLine(); + if (line) { + result.push(line); + } const relationships = child.getRelationships(); result.push(...relationships); diff --git a/packages/mindplot/src/components/TopicFeature.ts b/packages/mindplot/src/components/TopicFeature.ts index 307ad497..cd483e46 100644 --- a/packages/mindplot/src/components/TopicFeature.ts +++ b/packages/mindplot/src/components/TopicFeature.ts @@ -25,8 +25,8 @@ import Topic from './Topic'; import SvgIconModel from './model/SvgIconModel'; import LinkModel from './model/LinkModel'; import NoteModel from './model/NoteModel'; -import Icon from './Icon'; import EmojiIconModel from './model/EmojiIconModel'; +import Icon from './Icon'; class TopicFeatureFactory { static createIcon(topic: Topic, model: FeatureModel, readOnly: boolean): Icon { diff --git a/packages/mindplot/src/components/TopicStyle.ts b/packages/mindplot/src/components/TopicStyle.ts index 359aa802..0c6b8ed4 100644 --- a/packages/mindplot/src/components/TopicStyle.ts +++ b/packages/mindplot/src/components/TopicStyle.ts @@ -186,7 +186,7 @@ class TopicStyle { } static getInnerPadding(topic: Topic): number { - return Math.round(topic.getOrBuildTextShape().getFontHeight() * 0.5); + return topic.getOrBuildTextShape().getFontHeight() * 0.5; } static defaultShapeType(topic: Topic): TopicShapeType { diff --git a/packages/mindplot/src/components/commands/DragTopicCommand.ts b/packages/mindplot/src/components/commands/DragTopicCommand.ts index a0c0b6a6..95fe3e53 100644 --- a/packages/mindplot/src/components/commands/DragTopicCommand.ts +++ b/packages/mindplot/src/components/commands/DragTopicCommand.ts @@ -15,10 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { $assert } from '@wisemapping/core-js'; -import Point from '@wisemapping/web2d'; import Command from '../Command'; import CommandContext from '../CommandContext'; +import PositionType from '../PositionType'; import Topic from '../Topic'; class DragTopicCommand extends Command { @@ -26,11 +25,11 @@ class DragTopicCommand extends Command { private _parentId: number | null; - private _position: Point; + private _position: PositionType; private _order: number; - constructor(topicId: number, position: Point, order: number, parentTopic: Topic) { + constructor(topicId: number, position: PositionType, order: number, parentTopic: Topic) { super(); this._topicsId = topicId; this._parentId = parentTopic ? parentTopic.getId() : null; @@ -61,7 +60,7 @@ class DragTopicCommand extends Command { } else if (this._position != null) { commandContext.moveTopic(topic, this._position); } else { - $assert('Illegal command state exception.'); + throw new Error('Illegal command state exception.'); } // Finally, connect topic ... diff --git a/packages/mindplot/src/components/commands/MoveControlPointCommand.ts b/packages/mindplot/src/components/commands/MoveControlPointCommand.ts index ba0ab312..6001fed7 100644 --- a/packages/mindplot/src/components/commands/MoveControlPointCommand.ts +++ b/packages/mindplot/src/components/commands/MoveControlPointCommand.ts @@ -40,11 +40,11 @@ class MoveControlPointCommand extends Command { const relationship = commandContext.findRelationships([this._modelId])[0]; const model = relationship.getModel(); - let oldCtlPoint: PositionType; + let oldCtlPoint; switch (this._ctrIndex) { case PivotType.Start: oldCtlPoint = model.getSrcCtrlPoint(); - model.setSrcCtrlPoint(this._controlPoint); + model.setSrcCtrlPoint(this._controlPoint!); relationship.setIsSrcControlPointCustom(this._controlPoint != null); if (this._controlPoint) { relationship.setSrcControlPoint(this._controlPoint); @@ -52,7 +52,7 @@ class MoveControlPointCommand extends Command { break; case PivotType.End: oldCtlPoint = model.getDestCtrlPoint(); - model.setDestCtrlPoint(this._controlPoint); + model.setDestCtrlPoint(this._controlPoint!); relationship.setIsDestControlPointCustom(this._controlPoint != null); if (this._controlPoint) { relationship.setDestControlPoint(this._controlPoint); diff --git a/packages/mindplot/src/components/export/FreemindExporter.ts b/packages/mindplot/src/components/export/FreemindExporter.ts index 0b3f6a21..7e18f9c5 100644 --- a/packages/mindplot/src/components/export/FreemindExporter.ts +++ b/packages/mindplot/src/components/export/FreemindExporter.ts @@ -1,3 +1,20 @@ +/* + * Copyright [2021] [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. + */ import xmlFormatter from 'xml-formatter'; import { Mindmap } from '../..'; import INodeModel, { TopicShapeType } from '../model/INodeModel'; diff --git a/packages/mindplot/src/components/export/freemind/Map.ts b/packages/mindplot/src/components/export/freemind/Map.ts index 060efeee..df1df3d7 100644 --- a/packages/mindplot/src/components/export/freemind/Map.ts +++ b/packages/mindplot/src/components/export/freemind/Map.ts @@ -33,7 +33,9 @@ export default class Freemap { // Set map attributes const mapElem = document.createElement('map'); - mapElem.setAttribute('version', this.version); + if (this.version) { + mapElem.setAttribute('version', this.version); + } document.appendChild(mapElem); diff --git a/packages/mindplot/src/components/import/FreemindImporter.ts b/packages/mindplot/src/components/import/FreemindImporter.ts index 926d7c11..89b2bbd7 100644 --- a/packages/mindplot/src/components/import/FreemindImporter.ts +++ b/packages/mindplot/src/components/import/FreemindImporter.ts @@ -10,7 +10,6 @@ import FreemindEdge from '../export/freemind/Edge'; import FreemindIcon from '../export/freemind/Icon'; import FreemindHook from '../export/freemind/Hook'; import FreemindRichcontent from '../export/freemind/Richcontent'; -import FreemindArrowLink from '../export/freemind/Arrowlink'; import VersionNumber from '../export/freemind/importer/VersionNumber'; import FreemindIconConverter from './FreemindIconConverter'; import NoteModel from '../model/NoteModel'; @@ -28,8 +27,6 @@ export default class FreemindImporter extends Importer { private nodesmap!: Map; - private relationship!: Array; - private idDefault = 0; constructor(map: string) { @@ -40,7 +37,6 @@ export default class FreemindImporter extends Importer { import(nameMap: string, description: string): Promise { this.mindmap = new Mindmap(nameMap); this.nodesmap = new Map(); - this.relationship = new Array(); const parser = new DOMParser(); const freemindDoc = parser.parseFromString(this.freemindInput, 'application/xml'); @@ -95,19 +91,19 @@ export default class FreemindImporter extends Importer { mapRelaitonship.forEach((relationship: RelationshipModel) => { this.fixRelationshipControlPoints(relationship); - // Fix dest ID - const destId: string = relationship.getDestCtrlPoint(); - const destTopic: NodeModel | undefined = this.nodesmap.get(destId); - if (destTopic) { - relationship.setDestCtrlPoint(destTopic.getId()); - } + // // Fix dest ID + // const destId: string = relationship.getDestCtrlPoint(); + // const destTopic: NodeModel | undefined = this.nodesmap.get(destId); + // if (destTopic) { + // relationship.setDestCtrlPoint(destTopic.getId()); + // } - // Fix src ID - const srcId: string = relationship.getSrcCtrlPoint(); - const srcTopic: NodeModel | undefined = this.nodesmap.get(srcId); - if (srcTopic) { - relationship.setSrcCtrlPoint(srcTopic.getId()); - } + // // Fix src ID + // const srcId: string = relationship.getSrcCtrlPoint(); + // const srcTopic: NodeModel | undefined = this.nodesmap.get(srcId); + // if (srcTopic) { + // relationship.setSrcCtrlPoint(srcTopic.getId()); + // } mapRelaitonship.push(relationship); }); @@ -120,33 +116,33 @@ export default class FreemindImporter extends Importer { ); if (srcTopic && destNode) { // Fix x coord - const srcCtrlPoint: string = relationship.getSrcCtrlPoint(); + const srcCtrlPoint = relationship.getSrcCtrlPoint(); if (srcCtrlPoint) { const coords = srcTopic.getPosition(); if (coords.x < 0) { const x = coords.x * -1; - relationship.setSrcCtrlPoint(`${x},${coords.y}`); + relationship.setSrcCtrlPoint({ x, y: coords.y }); // Fix coord if (srcTopic.getOrder() && srcTopic.getOrder() % 2 !== 0) { const y = coords.y * -1; - relationship.setSrcCtrlPoint(`${coords.x},${y}`); + relationship.setSrcCtrlPoint({ x: coords.x, y }); } } } - const destCtrlPoint: string = relationship.getDestCtrlPoint(); + const destCtrlPoint = relationship.getDestCtrlPoint(); if (destCtrlPoint) { const coords = destNode.getPosition(); if (coords.x < 0) { const x = coords.x * -1; - relationship.setDestCtrlPoint(`${x},${coords.y}`); + relationship.setDestCtrlPoint({ x, y: coords.y }); } if (destNode.getOrder() && destNode.getOrder() % 2 !== 0) { const y = coords.y * -1; - relationship.setDestCtrlPoint(`${coords.x},${y}`); + relationship.setDestCtrlPoint({ x: coords.x, y }); } } } @@ -321,38 +317,38 @@ export default class FreemindImporter extends Importer { } } - if (child instanceof FreemindArrowLink) { - const arrow: FreemindArrowLink = child as FreemindArrowLink; - const relationship: RelationshipModel = new RelationshipModel(0, 0); - const destId = arrow.getDestination(); + // if (child instanceof FreemindArrowLink) { + // const arrow: FreemindArrowLink = child as FreemindArrowLink; + // const relationship: RelationshipModel = new RelationshipModel(0, 0); + // const destId = arrow.getDestination(); - relationship.setSrcCtrlPoint(destId); - relationship.setDestCtrlPoint(freeParent.getId()); - const endinclination = arrow.getEndInclination(); - if (endinclination) { - const inclination: Array = endinclination.split(';'); - relationship.setDestCtrlPoint(`${inclination[0]},${inclination[1]}`); - } + // relationship.setSrcCtrlPoint(destId); + // relationship.setDestCtrlPoint(freeParent.getId()); + // const endinclination = arrow.getEndInclination(); + // if (endinclination) { + // const inclination: Array = endinclination.split(';'); + // relationship.setDestCtrlPoint(`${ inclination[0]}, ${ inclination[1]}`); + // } - const startinclination = arrow.getStartinclination(); - if (startinclination) { - const inclination: Array = startinclination.split(';'); - relationship.setSrcCtrlPoint(`${inclination[0]},${inclination[1]}`); - } + // const startinclination = arrow.getStartinclination(); + // if (startinclination) { + // const inclination: Array = startinclination.split(';'); + // relationship.setSrcCtrlPoint(`${ inclination[0]}, ${ inclination[1]}`); + // } - const endarrow = arrow.getEndarrow(); - if (endarrow) { - relationship.setEndArrow(endarrow.toLowerCase() !== 'none'); - } + // const endarrow = arrow.getEndarrow(); + // if (endarrow) { + // relationship.setEndArrow(endarrow.toLowerCase() !== 'none'); + // } - const startarrow = arrow.getStartarrow(); - if (startarrow) { - relationship.setStartArrow(startarrow.toLowerCase() !== 'none'); - } + // const startarrow = arrow.getStartarrow(); + // if (startarrow) { + // relationship.setStartArrow(startarrow.toLowerCase() !== 'none'); + // } - relationship.setLineType(3); - this.relationship.push(relationship); - } + // relationship.setLineType(3); + // this.relationship.push(relationship); + // } }); } diff --git a/packages/mindplot/src/components/layout/LayoutManager.ts b/packages/mindplot/src/components/layout/LayoutManager.ts index 4a429745..297c6e20 100644 --- a/packages/mindplot/src/components/layout/LayoutManager.ts +++ b/packages/mindplot/src/components/layout/LayoutManager.ts @@ -111,8 +111,7 @@ class LayoutManager extends Events { return this; } - removeNode(id: number) { - $assert($defined(id), 'id can not be null'); + removeNode(id: number): LayoutManager { const node = this._treeSet.find(id); // Is It connected ? @@ -166,7 +165,7 @@ class LayoutManager extends Events { return canvas; } - layout(flush: boolean): LayoutManager { + layout(flush?: boolean): LayoutManager { // File repositioning ... this._layout.layout(); diff --git a/packages/mindplot/src/components/model/FeatureModel.ts b/packages/mindplot/src/components/model/FeatureModel.ts index 27a32afd..9bc89bd4 100644 --- a/packages/mindplot/src/components/model/FeatureModel.ts +++ b/packages/mindplot/src/components/model/FeatureModel.ts @@ -76,7 +76,7 @@ class FeatureModel { } setId(id: number) { - $assert(Number.isFinite(id)); + $assert(Number.isFinite(id), `id is not a number ${id}`); this._id = id; } diff --git a/packages/mindplot/src/components/model/INodeModel.ts b/packages/mindplot/src/components/model/INodeModel.ts index a7e43e5a..ee61a24f 100644 --- a/packages/mindplot/src/components/model/INodeModel.ts +++ b/packages/mindplot/src/components/model/INodeModel.ts @@ -58,7 +58,7 @@ abstract class INodeModel { this.putProperty('id', newId); } else { if (id > INodeModel._nextUuid) { - $assert(Number.isFinite(id)); + $assert(Number.isFinite(id), `value is not a number ${id}`); INodeModel._nextUuid = id; } this.putProperty('id', id); diff --git a/packages/mindplot/src/components/model/NodeModel.ts b/packages/mindplot/src/components/model/NodeModel.ts index 2ea1b93b..f7f4830e 100644 --- a/packages/mindplot/src/components/model/NodeModel.ts +++ b/packages/mindplot/src/components/model/NodeModel.ts @@ -108,7 +108,6 @@ class NodeModel extends INodeModel { * @throws will throw an error if key is null or undefined */ putProperty(key: string, value: string | number | boolean): void { - $defined(key, 'key can not be null'); this._properties[key] = value; } @@ -117,7 +116,6 @@ class NodeModel extends INodeModel { } getProperty(key: string): number | string | boolean | undefined { - $defined(key, 'key can not be null'); return this._properties[key]; } diff --git a/packages/mindplot/src/components/model/RelationshipModel.ts b/packages/mindplot/src/components/model/RelationshipModel.ts index 261f01e8..6609f7bc 100644 --- a/packages/mindplot/src/components/model/RelationshipModel.ts +++ b/packages/mindplot/src/components/model/RelationshipModel.ts @@ -16,8 +16,8 @@ * limitations under the License. */ import { $assert, $defined } from '@wisemapping/core-js'; -import Point from '@wisemapping/web2d'; import { LineType } from '../ConnectionLine'; +import PositionType from '../PositionType'; class RelationshipModel { static _nextUuid = 0; @@ -30,9 +30,9 @@ class RelationshipModel { private _lineType: LineType; - private _srcCtrlPoint: Point; + private _srcCtrlPoint: PositionType | null; - private _destCtrlPoint: Point; + private _destCtrlPoint: PositionType | null; private _endArrow: boolean; @@ -75,19 +75,19 @@ class RelationshipModel { this._lineType = lineType; } - getSrcCtrlPoint(): Point { + getSrcCtrlPoint(): PositionType | null { return this._srcCtrlPoint; } - setSrcCtrlPoint(srcCtrlPoint: Point) { + setSrcCtrlPoint(srcCtrlPoint: PositionType): void { this._srcCtrlPoint = srcCtrlPoint; } - getDestCtrlPoint(): Point { + getDestCtrlPoint(): PositionType | null { return this._destCtrlPoint; } - setDestCtrlPoint(destCtrlPoint: Point): void { + setDestCtrlPoint(destCtrlPoint: PositionType): void { this._destCtrlPoint = destCtrlPoint; } diff --git a/packages/mindplot/src/components/persistence/XMLSerializerBeta.ts b/packages/mindplot/src/components/persistence/XMLSerializerBeta.ts index 6cc6f7e7..47e35c38 100644 --- a/packages/mindplot/src/components/persistence/XMLSerializerBeta.ts +++ b/packages/mindplot/src/components/persistence/XMLSerializerBeta.ts @@ -32,7 +32,7 @@ class XMLSerializerBeta implements XMLMindmapSerializer { // Store map attributes ... const mapElem = document.createElement('map'); const name = mindmap.getId(); - if ($defined(name)) { + if (name) { mapElem.setAttribute('name', name); } document.append(mapElem); diff --git a/packages/mindplot/src/components/persistence/XMLSerializerTango.ts b/packages/mindplot/src/components/persistence/XMLSerializerTango.ts index fbb09060..b0441ed9 100644 --- a/packages/mindplot/src/components/persistence/XMLSerializerTango.ts +++ b/packages/mindplot/src/components/persistence/XMLSerializerTango.ts @@ -222,13 +222,19 @@ class XMLSerializerTango implements XMLMindmapSerializer { const lineType = relationship.getLineType(); result.setAttribute('lineType', lineType.toString()); - if ($defined(relationship.getSrcCtrlPoint())) { - const srcPoint = relationship.getSrcCtrlPoint(); - result.setAttribute('srcCtrlPoint', `${Math.round(srcPoint.x)},${Math.round(srcPoint.y)}`); + const strCtrlPoint = relationship.getSrcCtrlPoint(); + if (strCtrlPoint) { + result.setAttribute( + 'srcCtrlPoint', + `${Math.round(strCtrlPoint.x)},${Math.round(strCtrlPoint.y)}`, + ); } - if ($defined(relationship.getDestCtrlPoint())) { - const destPoint = relationship.getDestCtrlPoint(); - result.setAttribute('destCtrlPoint', `${Math.round(destPoint.x)},${Math.round(destPoint.y)}`); + const destCtrPoint = relationship.getDestCtrlPoint(); + if (destCtrPoint) { + result.setAttribute( + 'destCtrlPoint', + `${Math.round(destCtrPoint.x)},${Math.round(destCtrPoint.y)}`, + ); } result.setAttribute('endArrow', String(relationship.getEndArrow())); result.setAttribute('startArrow', String(relationship.getStartArrow())); @@ -518,20 +524,20 @@ class XMLSerializerTango implements XMLMindmapSerializer { const model = mindmap.createRelationship(srcId, destId); model.setLineType(lineType); if (srcCtrlPoint) { - const spoint = Point.fromString(srcCtrlPoint); - if (spoint) { + try { + const spoint = Point.fromString(srcCtrlPoint); model.setSrcCtrlPoint(spoint); - } else { - console.error(`srcCtrlPoint could not be parsed: ${srcCtrlPoint}`); + } catch (e) { + console.error(e); } } if (destCtrlPoint) { - const dpoint = Point.fromString(destCtrlPoint); - if (dpoint) { + try { + const dpoint = Point.fromString(destCtrlPoint); model.setDestCtrlPoint(dpoint); - } else { - console.error(`destCtrlPoint could not be parsed: ${destCtrlPoint}`); + } catch (e) { + console.error(e); } } diff --git a/packages/mindplot/src/components/util/Shape.ts b/packages/mindplot/src/components/util/Shape.ts index 0b07f96e..b084c8d7 100644 --- a/packages/mindplot/src/components/util/Shape.ts +++ b/packages/mindplot/src/components/util/Shape.ts @@ -15,7 +15,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Point } from '@wisemapping/web2d'; import { $assert } from '@wisemapping/core-js'; import TopicConfig from '../TopicConfig'; import PositionType from '../PositionType'; @@ -110,7 +109,10 @@ class Shape { const x2 = tarPos.x + Math.sqrt((l * l) / (1 + m * m)) * fix * -1; const y2 = m * (x2 - tarPos.x) + tarPos.y; - return [new Point(-srcPos.x + x1, -srcPos.y + y1), new Point(-tarPos.x + x2, -tarPos.y + y2)]; + return [ + { x: -srcPos.x + x1, y: -srcPos.y + y1 }, + { x: -tarPos.x + x2, y: -tarPos.y + y2 }, + ]; } static workoutIncomingConnectionPoint(targetNode: Topic, sourcePosition: PositionType) { diff --git a/packages/mindplot/storybook/src/stories/Layout.stories.ts b/packages/mindplot/storybook/src/stories/Layout.stories.ts new file mode 100644 index 00000000..600a3610 --- /dev/null +++ b/packages/mindplot/storybook/src/stories/Layout.stories.ts @@ -0,0 +1,174 @@ +/* eslint-disable no-new */ +import { Story, Meta } from '@storybook/html'; +import BalancedTestSuite from './layout/BalancedTestSuite'; + +import Raphael from './layout/lib/raphael-min'; +import { drawGrid } from './layout/lib/raphael-plugins'; +import TestSuite from './layout/TestSuite'; + +global.Raphael = Raphael; +global.Raphael.fn.drawGrid = drawGrid; + +export default { + title: 'Mindplot/Layout', + // More on argTypes: https://storybook.js.org/docs/html/api/argtypes + argTypes: {}, +} as Meta; + +const fullSuite = () => { + const divElem = document.createElement('div'); + + divElem.innerHTML = ` + + + + + + +`; + window.addEventListener('DOMContentLoaded', () => { + new TestSuite(); + new BalancedTestSuite(); + // @todo: Review ... + // new SymmetricTestSuite(); + }); + + return divElem; +}; + +const Template: Story = () => fullSuite(); +export const BasicSuite = Template.bind({}); diff --git a/packages/mindplot/storybook/src/stories/Topic.stories.ts b/packages/mindplot/storybook/src/stories/Topic.stories.ts index a9a447fa..fedc19bf 100644 --- a/packages/mindplot/storybook/src/stories/Topic.stories.ts +++ b/packages/mindplot/storybook/src/stories/Topic.stories.ts @@ -26,8 +26,8 @@ export default { const Template: Story = (args: TopicArgs) => createTopic(args); -export const BoderderStyle = Template.bind({}); -BoderderStyle.args = { +export const BorderStyle = Template.bind({}); +BorderStyle.args = { text: 'Border Style', borderColor: '#52E661', }; diff --git a/packages/mindplot/storybook/src/stories/Topic.ts b/packages/mindplot/storybook/src/stories/Topic.ts index 581fb9f8..fb5f48f3 100644 --- a/packages/mindplot/storybook/src/stories/Topic.ts +++ b/packages/mindplot/storybook/src/stories/Topic.ts @@ -3,7 +3,7 @@ import $ from 'jquery'; import { LinkModel, Mindmap, NoteModel, Topic } from '../../../src'; import NodeModel from '../../../src/components/model/NodeModel'; import CentralTopic from '../../../src/components/CentralTopic'; -import Workspace from '../../../src/components/Workspace'; +import Canvas from '../../../src/components/Canvas'; import ScreenManager from '../../../src/components/ScreenManager'; import EmojiIconModel from '../../../src/components/model/EmojiIconModel'; import TopicEventDispatcher from '../../../src/components/TopicEventDispatcher'; @@ -59,7 +59,7 @@ const createTopic = ({ // Initialize designer helpers ... const screenManager = new ScreenManager(divElem); - const workspace = new Workspace(screenManager, 0.3, readOnly); + const workspace = new Canvas(screenManager, 0.3, readOnly); TopicEventDispatcher.configure(readOnly); // Update model ... diff --git a/packages/mindplot/test/playground/layout/BalancedTestSuite.js b/packages/mindplot/storybook/src/stories/layout/BalancedTestSuite.js similarity index 99% rename from packages/mindplot/test/playground/layout/BalancedTestSuite.js rename to packages/mindplot/storybook/src/stories/layout/BalancedTestSuite.js index 8acde71b..decc3e48 100644 --- a/packages/mindplot/test/playground/layout/BalancedTestSuite.js +++ b/packages/mindplot/storybook/src/stories/layout/BalancedTestSuite.js @@ -18,7 +18,7 @@ import $ from 'jquery'; import { $assert } from '@wisemapping/core-js'; import TestSuite from './TestSuite'; -import LayoutManager from '../../../src/components/layout/LayoutManager'; +import LayoutManager from '../../../../src/components/layout/LayoutManager'; class BalancedTestSuite extends TestSuite { constructor() { diff --git a/packages/mindplot/test/playground/layout/SymmetricTestSuite.js b/packages/mindplot/storybook/src/stories/layout/SymmetricTestSuite.js similarity index 100% rename from packages/mindplot/test/playground/layout/SymmetricTestSuite.js rename to packages/mindplot/storybook/src/stories/layout/SymmetricTestSuite.js diff --git a/packages/mindplot/test/playground/layout/TestSuite.js b/packages/mindplot/storybook/src/stories/layout/TestSuite.js similarity index 99% rename from packages/mindplot/test/playground/layout/TestSuite.js rename to packages/mindplot/storybook/src/stories/layout/TestSuite.js index ed84e090..81606c60 100644 --- a/packages/mindplot/test/playground/layout/TestSuite.js +++ b/packages/mindplot/storybook/src/stories/layout/TestSuite.js @@ -18,8 +18,8 @@ */ import $ from 'jquery'; import { $assert } from '@wisemapping/core-js'; -import LayoutManager from '../../../src/components/layout/LayoutManager'; -import ChildrenSorterStrategy from '../../../src/components/layout/ChildrenSorterStrategy'; +import LayoutManager from '../../../../src/components/layout/LayoutManager'; +import ChildrenSorterStrategy from '../../../../src/components/layout/ChildrenSorterStrategy'; class TestSuite extends ChildrenSorterStrategy { constructor() { diff --git a/packages/mindplot/test/playground/layout/lib/raphael-min.js b/packages/mindplot/storybook/src/stories/layout/lib/raphael-min.js similarity index 100% rename from packages/mindplot/test/playground/layout/lib/raphael-min.js rename to packages/mindplot/storybook/src/stories/layout/lib/raphael-min.js diff --git a/packages/mindplot/test/playground/layout/lib/raphael-plugins.js b/packages/mindplot/storybook/src/stories/layout/lib/raphael-plugins.js similarity index 100% rename from packages/mindplot/test/playground/layout/lib/raphael-plugins.js rename to packages/mindplot/storybook/src/stories/layout/lib/raphael-plugins.js diff --git a/packages/mindplot/test/playground/layout/sample.xml b/packages/mindplot/storybook/src/stories/layout/sample.xml similarity index 100% rename from packages/mindplot/test/playground/layout/sample.xml rename to packages/mindplot/storybook/src/stories/layout/sample.xml diff --git a/packages/mindplot/test/playground/layout/utils.js b/packages/mindplot/storybook/src/stories/utils.js similarity index 100% rename from packages/mindplot/test/playground/layout/utils.js rename to packages/mindplot/storybook/src/stories/utils.js diff --git a/packages/mindplot/test/playground/index.html b/packages/mindplot/test/playground/index.html deleted file mode 100644 index 027af222..00000000 --- a/packages/mindplot/test/playground/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - WiseMapping - Mindplot Playground - - - - - -

WiseMapping Mindplot - Playground

-

You will find here a set of examples that shows how you can use integrate WiseMapping Mindplot.

-
- -
- - - diff --git a/packages/mindplot/test/playground/layout/context-loader.js b/packages/mindplot/test/playground/layout/context-loader.js deleted file mode 100644 index 2575c6bf..00000000 --- a/packages/mindplot/test/playground/layout/context-loader.js +++ /dev/null @@ -1,15 +0,0 @@ -import TestSuite from './TestSuite'; -import BalancedTestSuite from './BalancedTestSuite'; -import SymmetricTestSuite from './SymmetricTestSuite'; -import Raphael from './lib/raphael-min'; -import { drawGrid } from './lib/raphael-plugins'; -import '../../../src'; // TODO: remove this when removing mootools (hack used to load it as a side effect) - -global.Raphael = Raphael; -global.Raphael.fn.drawGrid = drawGrid; - -window.addEventListener('DOMContentLoaded', () => { - new TestSuite(); - new BalancedTestSuite(); - new SymmetricTestSuite(); -}); diff --git a/packages/mindplot/test/playground/layout/index.html b/packages/mindplot/test/playground/layout/index.html deleted file mode 100644 index d298c71d..00000000 --- a/packages/mindplot/test/playground/layout/index.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/packages/mindplot/test/playground/lib/raphael-plugins.js b/packages/mindplot/test/playground/lib/raphael-plugins.js deleted file mode 100644 index c823c9a6..00000000 --- a/packages/mindplot/test/playground/lib/raphael-plugins.js +++ /dev/null @@ -1,29 +0,0 @@ -Raphael.fn.drawGrid = function (x, y, w, h, wv, hv, color) { - color = color || '#999'; - let path = ['M', x, y, 'L', x + w, y, x + w, y + h, x, y + h, x, y]; - const rowHeight = h / hv; - const columnWidth = w / wv; - for (var i = 0; i < hv + 1; i++) { - var offset = y + i * rowHeight; - path = this.path(['M', x, offset, 'L', x + w, y + i * rowHeight]); - if (offset == 0 || offset == h) { - path.attr({ stroke: '#000' }); - } else if (offset == h / 2) { - path.attr({ stroke: '#c00' }); - } else { - path.attr({ stroke: '#999' }); - } - } - for (var i = 0; i < wv + 1; i++) { - var offset = x + i * columnWidth; - path = this.path(['M', offset, y, 'L', x + i * columnWidth, y + h]); - if (offset == 0 || offset == w) { - path.attr({ stroke: '#000' }); - } else if (offset == w / 2) { - path.attr({ stroke: '#c00' }); - } else { - path.attr({ stroke: '#999' }); - } - } - return this.path; -}; diff --git a/packages/mindplot/test/unit/layout/BalancedTestSuite.test.js b/packages/mindplot/test/unit/layout/BalancedTestSuite.test.js deleted file mode 100644 index 48c930be..00000000 --- a/packages/mindplot/test/unit/layout/BalancedTestSuite.test.js +++ /dev/null @@ -1,328 +0,0 @@ -import Constants from './Constants'; -import LayoutManager from '../../../src/components/layout/LayoutManager'; - -describe('Balanced Test Suite', () => { - describe('balancedTest', () => { - const position = { x: 0, y: 0 }; - const manager = new LayoutManager(0, Constants.ROOT_NODE_SIZE); - manager.addNode(1, Constants.NODE_SIZE, position); - manager.connectNode(0, 1, 0); - manager.layout(); - - manager.addNode(2, Constants.NODE_SIZE, position); - manager.connectNode(0, 2, 1); - manager.layout(); - - manager.addNode(3, Constants.NODE_SIZE, position); - manager.connectNode(0, 3, 2); - manager.layout(); - - manager.addNode(4, Constants.NODE_SIZE, position); - manager.connectNode(0, 4, 3); - manager.layout(); - - manager.addNode(5, Constants.NODE_SIZE, position); - manager.connectNode(0, 5, 4); - manager.layout(); - - manager.addNode(6, Constants.NODE_SIZE, position); - manager.connectNode(0, 6, 5); - manager.layout(); - - manager.addNode(7, Constants.NODE_SIZE, position); - manager.addNode(8, Constants.NODE_SIZE, position); - manager.addNode(9, Constants.NODE_SIZE, position); - manager.connectNode(3, 7, 0); - manager.connectNode(7, 8, 0); - manager.connectNode(7, 9, 1); - manager.layout(); - - manager.addNode(10, Constants.NODE_SIZE, position); - manager.addNode(11, Constants.NODE_SIZE, position); - manager.addNode(12, Constants.NODE_SIZE, position); - manager.connectNode(6, 10, 0); - manager.connectNode(10, 11, 0); - manager.connectNode(10, 12, 1); - manager.layout(); - - manager.addNode(13, Constants.NODE_SIZE, position); - manager.connectNode(0, 13, 4); - manager.layout(); - - test('Check orders have shifted accordingly', () => { - expect(manager.find(5).getOrder()).toEqual(6); - }); - - test('Check orders have shifted accordingly', () => { - manager.addNode(14, Constants.NODE_SIZE, position); - manager.connectNode(0, 14, 5); - manager.layout(); - expect(manager.find(6).getOrder()).toEqual(7); - }); - - test('Check orders have shifted accordingly', () => { - manager.addNode(15, Constants.NODE_SIZE, position); - manager.connectNode(0, 15, 4); - manager.layout(); - expect(manager.find(13).getOrder()).toEqual(6); - expect(manager.find(5).getOrder()).toEqual(8); - }); - - test('Check orders have shifted accordingly', () => { - manager.addNode(16, Constants.NODE_SIZE, position); - manager.connectNode(0, 16, 25); - manager.layout(); - expect(manager.find(16).getOrder()).toEqual(9); - }); - - test('Check that everything is ok', () => { - manager.addNode(17, Constants.NODE_SIZE, position); - manager.addNode(18, Constants.NODE_SIZE, position); - manager.addNode(19, Constants.NODE_SIZE, position); - manager.connectNode(0, 17, 11); - manager.connectNode(0, 18, 13); - manager.connectNode(0, 19, 10); - manager.layout(); - expect(manager.find(1).getPosition().x).toBeGreaterThan(manager.find(0).getPosition().x); - expect(manager.find(3).getPosition().x).toBeGreaterThan(manager.find(0).getPosition().x); - expect(manager.find(5).getPosition().x).toBeGreaterThan(manager.find(0).getPosition().x); - expect(manager.find(2).getPosition().x).toBeLessThan(manager.find(0).getPosition().x); - expect(manager.find(4).getPosition().x).toBeLessThan(manager.find(0).getPosition().x); - expect(manager.find(6).getPosition().x).toBeLessThan(manager.find(0).getPosition().x); - expect(manager.find(7).getPosition().x).toBeGreaterThan(manager.find(3).getPosition().x); - expect(manager.find(8).getPosition().x).toBeGreaterThan(manager.find(7).getPosition().x); - expect(manager.find(9).getPosition().x).toBeGreaterThan(manager.find(7).getPosition().x); - expect(manager.find(10).getPosition().x).toBeLessThan(manager.find(6).getPosition().x); - expect(manager.find(11).getPosition().x).toBeLessThan(manager.find(10).getPosition().x); - expect(manager.find(12).getPosition().x).toBeLessThan(manager.find(10).getPosition().x); - }); - }); - - describe('balancedPredictTest', () => { - const position = { x: 0, y: 0 }; - const manager = new LayoutManager(0, Constants.ROOT_NODE_SIZE); - - manager.addNode(1, Constants.NODE_SIZE, position); - manager.addNode(2, Constants.NODE_SIZE, position); - manager.addNode(3, Constants.NODE_SIZE, position); - manager.addNode(4, Constants.NODE_SIZE, position); - manager.addNode(5, Constants.NODE_SIZE, position); - manager.addNode(7, Constants.NODE_SIZE, position); - manager.addNode(8, Constants.NODE_SIZE, position); - manager.addNode(9, Constants.NODE_SIZE, position); - manager.addNode(10, Constants.NODE_SIZE, position); - manager.addNode(11, Constants.NODE_SIZE, position); - - manager.connectNode(0, 1, 0); - manager.connectNode(0, 2, 1); - manager.connectNode(0, 3, 2); - manager.connectNode(0, 4, 3); - manager.connectNode(0, 5, 4); - manager.connectNode(4, 7, 0); - manager.connectNode(4, 8, 1); - manager.connectNode(8, 9, 0); - manager.connectNode(3, 10, 0); - manager.connectNode(3, 11, 1); - - manager.layout(); - - test('Added as child of node 0 and dropped at (165, -70)', () => { - const prediction1a = manager.predict(0, null, { x: 165, y: -70 }); - expect(prediction1a.position.y).toBeLessThan(manager.find(1).getPosition().y); - expect(prediction1a.position.x).toEqual(manager.find(1).getPosition().x); - expect(prediction1a.order).toEqual(0); - }); - - test('Added as child of node 0 and dropped at (165, -10)', () => { - const prediction1b = manager.predict(0, null, { x: 165, y: -10 }); - expect(prediction1b.position.y).toBeGreaterThan(manager.find(1).getPosition().y); - expect(prediction1b.position.y).toBeLessThan(manager.find(3).getPosition().y); - expect(prediction1b.position.x).toEqual(manager.find(1).getPosition().x); - expect(prediction1b.order).toEqual(2); - }); - - test('Added as child of node 0 and dropped at (145, 15)', () => { - const prediction1c = manager.predict(0, null, { x: 145, y: 15 }); - expect(prediction1c.position.y).toBeGreaterThan(manager.find(3).getPosition().y); - expect(prediction1c.position.y).toBeLessThan(manager.find(5).getPosition().y); - expect(prediction1c.position.x).toEqual(manager.find(3).getPosition().x); - expect(prediction1c.order).toEqual(4); - }); - - test('Added as child of node 0 and dropped at (145, 70)', () => { - const prediction1d = manager.predict(0, null, { x: 145, y: 70 }); - expect(prediction1d.position.y).toBeGreaterThan(manager.find(5).getPosition().y); - expect(prediction1d.position.x).toEqual(manager.find(5).getPosition().x); - expect(prediction1d.order).toEqual(6); - }); - - test('Added as child of node 0 and dropped at (-145, -50)', () => { - const prediction2a = manager.predict(0, null, { x: -145, y: -50 }); - expect(prediction2a.position.y).toBeLessThan(manager.find(2).getPosition().y); - expect(prediction2a.position.x).toEqual(manager.find(2).getPosition().x); - expect(prediction2a.order).toEqual(1); - }); - - test('Added as child of node 0 and dropped at (-145, -10)', () => { - const prediction2b = manager.predict(0, null, { x: -145, y: -10 }); - expect(prediction2b.position.y).toBeGreaterThan(manager.find(2).getPosition().y); - expect(prediction2b.position.y).toBeLessThan(manager.find(4).getPosition().y); - expect(prediction2b.position.x).toEqual(manager.find(2).getPosition().x); - expect(prediction2b.order).toEqual(3); - }); - - test('Added as child of node 0 and dropped at (-145, 40)', () => { - const prediction2c = manager.predict(0, null, { x: -145, y: 400 }); - expect(prediction2c.position.y).toBeGreaterThan(manager.find(4).getPosition().y); - expect(prediction2c.position.x).toEqual(manager.find(4).getPosition().x); - expect(prediction2c.order).toEqual(5); - }); - - test('Predict nodes added with no position', () => { - const prediction3 = manager.predict(0, null, null); - expect(prediction3.position.y).toBeGreaterThan(manager.find(4).getPosition().y); - expect(prediction3.position.x).toEqual(manager.find(4).getPosition().x); - expect(prediction3.order).toEqual(5); - - manager.addNode(6, Constants.NODE_SIZE, prediction3.position); - manager.connectNode(0, 6, prediction3.order); - manager.layout(); - - const prediction4 = manager.predict(0, null, null); - expect(prediction4.position.y).toBeGreaterThan(manager.find(5).getPosition().y); - expect(prediction4.position.x).toEqual(manager.find(5).getPosition().x); - expect(prediction4.order).toEqual(6); - }); - - test('Predict nodes added only a root node', () => { - manager.removeNode(1).removeNode(2).removeNode(3).removeNode(4).removeNode(5); - manager.layout(); - const prediction5a = manager.predict(0, null, null); - const prediction5b = manager.predict(0, null, { x: 40, y: 100 }); - expect(prediction5a.position.x).toBeGreaterThan(manager.find(0).getPosition().x); - expect(prediction5a.position.y).toEqual(manager.find(0).getPosition().y); - expect(prediction5a.order).toEqual(0); - expect(prediction5a.position.x).toEqual(prediction5b.position.x); - expect(prediction5a.position.y).toEqual(prediction5b.position.y); - expect(prediction5a.order).toEqual(prediction5b.order); - }); - }); - - describe('balancedNodeDragPredictTest', () => { - const position = { x: 0, y: 0 }; - const manager = new LayoutManager(0, Constants.ROOT_NODE_SIZE); - - manager.addNode(1, Constants.NODE_SIZE, position).connectNode(0, 1, 0); - manager.layout(); - - describe('Predict 1', () => { - test('Node drag predict A', () => { - const prediction1a = manager.predict(0, 1, { x: 50, y: 50 }); - expect(prediction1a.position.x).toEqual(manager.find(1).getPosition().x); - expect(prediction1a.position.y).toEqual(manager.find(1).getPosition().y); - expect(prediction1a.order).toEqual(manager.find(1).getOrder()); - }); - - test('Node drag predict B', () => { - const prediction1b = manager.predict(0, 1, { x: 50, y: -50 }); - expect(prediction1b.position.x).toEqual(manager.find(1).getPosition().x); - expect(prediction1b.position.y).toEqual(manager.find(1).getPosition().y); - expect(prediction1b.order).toEqual(manager.find(1).getOrder()); - }); - - test('Node drag predict C', () => { - const prediction1c = manager.predict(0, 1, { x: -50, y: 50 }); - expect(prediction1c.position.x).toBeLessThan(manager.find(0).getPosition().x); - expect(prediction1c.position.y).toEqual(manager.find(0).getPosition().y); - expect(prediction1c.order).toEqual(1); - }); - - test('Node drag predict D', () => { - const prediction1d = manager.predict(0, 1, { x: -50, y: -50 }); - expect(prediction1d.position.x).toBeLessThan(manager.find(0).getPosition().x); - expect(prediction1d.position.y).toEqual(manager.find(0).getPosition().y); - expect(prediction1d.order).toEqual(1); - }); - }); - - describe('Predict 2', () => { - beforeEach(() => { - manager.disconnectNode(1); - manager.connectNode(0, 1, 1); - manager.layout(); - }); - - test('Node drag predict A', () => { - const prediction2a = manager.predict(0, 1, { x: 50, y: 50 }); - expect(prediction2a.position.x).toBeGreaterThan(manager.find(0).getPosition().x); - expect(prediction2a.position.y).toEqual(manager.find(0).getPosition().y); - expect(prediction2a.order).toEqual(0); - }); - - test('Node drag predict B', () => { - const prediction2b = manager.predict(0, 1, { x: 50, y: -50 }); - expect(prediction2b.position.x).toBeGreaterThan(manager.find(0).getPosition().x); - expect(prediction2b.position.y).toEqual(manager.find(0).getPosition().y); - expect(prediction2b.order).toEqual(0); - }); - - test('Node drag predict C', () => { - const prediction2c = manager.predict(0, 1, { x: -50, y: 50 }); - expect(prediction2c.position.x).toEqual(manager.find(1).getPosition().x); - expect(prediction2c.position.y).toEqual(manager.find(1).getPosition().y); - expect(prediction2c.order).toEqual(manager.find(1).getOrder()); - }); - - test('Node drag predict D', () => { - const prediction2d = manager.predict(0, 1, { x: -50, y: -50 }); - expect(prediction2d.position.x).toEqual(manager.find(1).getPosition().x); - expect(prediction2d.position.y).toEqual(manager.find(1).getPosition().y); - expect(prediction2d.order).toEqual(manager.find(1).getOrder()); - }); - }); - - describe('Predict 3', () => { - beforeAll(() => { - manager.disconnectNode(1); - manager.connectNode(0, 1, 0); - manager.addNode(2, Constants.NODE_SIZE, position).connectNode(0, 2, 2); - manager.layout(); - }); - - test('Node drag predict A', () => { - const prediction3a = manager.predict(0, 1, { x: 50, y: 50 }); - expect(prediction3a.position.x).toEqual(manager.find(2).getPosition().x); - expect(prediction3a.position.y).toBeGreaterThan(manager.find(2).getPosition().y); - expect(prediction3a.order).toEqual(4); - }); - - test('Node drag predict B', () => { - const prediction3b = manager.predict(0, 1, { x: 50, y: -50 }); - expect(prediction3b.position.x).toEqual(manager.find(1).getPosition().x); - expect(prediction3b.position.y).toEqual(manager.find(1).getPosition().y); - expect(prediction3b.order).toEqual(manager.find(1).getOrder()); - }); - - test('Node drag predict C', () => { - const prediction3c = manager.predict(0, 1, { x: -50, y: 50 }); - expect(prediction3c.position.x).toBeLessThan(manager.find(0).getPosition().x); - expect(prediction3c.position.y).toEqual(manager.find(0).getPosition().y); - expect(prediction3c.order).toEqual(1); - }); - - test('Node drag predict D', () => { - const prediction3d = manager.predict(0, 1, { x: -50, y: -50 }); - expect(prediction3d.position.x).toBeLessThan(manager.find(0).getPosition().x); - expect(prediction3d.position.y).toEqual(manager.find(0).getPosition().y); - expect(prediction3d.order).toEqual(1); - }); - - test('Node drag predict E', () => { - const prediction3e = manager.predict(0, 1, { x: 50, y: 0 }); - expect(prediction3e.position.x).toEqual(manager.find(1).getPosition().x); - expect(prediction3e.position.y).toEqual(manager.find(1).getPosition().y); - expect(prediction3e.order).toEqual(manager.find(1).getOrder()); - }); - }); - }); -}); diff --git a/packages/mindplot/test/unit/layout/Constants.ts b/packages/mindplot/test/unit/layout/Constants.ts deleted file mode 100644 index be6b5f30..00000000 --- a/packages/mindplot/test/unit/layout/Constants.ts +++ /dev/null @@ -1,5 +0,0 @@ -const Constants = { - NODE_SIZE: { width: 80, height: 30 }, - ROOT_NODE_SIZE: { width: 120, height: 40 }, -}; -export default Constants; diff --git a/packages/mindplot/test/unit/layout/EventsTestSuite.test.js b/packages/mindplot/test/unit/layout/EventsTestSuite.test.js deleted file mode 100644 index 60f20446..00000000 --- a/packages/mindplot/test/unit/layout/EventsTestSuite.test.js +++ /dev/null @@ -1,61 +0,0 @@ -import Events from '../../../src/components/Events'; - -describe('Events class suite', () => { - class TestClass extends Events { - getEvents() { - return this._handlerByType; - } - - removeEvents() { - this._handlerByType = {}; - } - } - - const expectedChangeFn1 = () => 'change1'; - const expectedChangeFn2 = () => 'change2'; - const expectedLoadFn = () => 'loaded'; - const myTestClass = new TestClass(); - - describe('addEventTest', () => { - afterAll(() => { - myTestClass.removeEvents(); - }); - - test('Added event Change', () => { - expect(myTestClass.getEvents()).toEqual({}); - myTestClass.addEvent('change', expectedChangeFn1); - }); - - test('Added event Change', () => { - expect(myTestClass.getEvents()).toEqual({ change: [expectedChangeFn1] }); - myTestClass.addEvent('change', expectedChangeFn2); - }); - - test('Added event Load', () => { - expect(myTestClass.getEvents()).toEqual({ change: [expectedChangeFn1, expectedChangeFn2] }); - myTestClass.addEvent('load', expectedLoadFn); - expect(myTestClass.getEvents()).toEqual({ - change: [expectedChangeFn1, expectedChangeFn2], - load: [expectedLoadFn], - }); - }); - }); - - describe('removeEventTest', () => { - afterAll(() => { - myTestClass.removeEvents(); - }); - - test('Added 2 event change', () => { - expect(myTestClass.getEvents()).toEqual({}); - myTestClass.addEvent('change', expectedChangeFn1); - myTestClass.addEvent('change', expectedChangeFn2); - }); - - test('Remove 1 event change', () => { - expect(myTestClass.getEvents()).toEqual({ change: [expectedChangeFn1, expectedChangeFn2] }); - myTestClass.removeEvent('change', expectedChangeFn1); - expect(myTestClass.getEvents()).toEqual({ change: [expectedChangeFn2] }); - }); - }); -}); diff --git a/packages/mindplot/test/unit/layout/SymmetricTestSuite.test.js b/packages/mindplot/test/unit/layout/SymmetricTestSuite.test.js deleted file mode 100644 index 1f276b01..00000000 --- a/packages/mindplot/test/unit/layout/SymmetricTestSuite.test.js +++ /dev/null @@ -1,97 +0,0 @@ -import Constants from './Constants'; -import LayoutManager from '../../../src/components/layout/LayoutManager'; - -describe('Symmetric Test Suite', () => { - describe('symmetricTest', () => { - const position = { x: 0, y: 0 }; - const manager = new LayoutManager(0, Constants.ROOT_NODE_SIZE); - - manager.addNode(1, Constants.NODE_SIZE, position); - manager.addNode(2, Constants.NODE_SIZE, position); - manager.addNode(3, Constants.NODE_SIZE, position); - manager.addNode(4, Constants.NODE_SIZE, position); - manager.addNode(5, Constants.NODE_SIZE, position); - manager.addNode(6, Constants.NODE_SIZE, position); - manager.addNode(7, Constants.NODE_SIZE, position); - manager.addNode(8, Constants.NODE_SIZE, position); - manager.addNode(9, Constants.NODE_SIZE, position); - manager.addNode(10, Constants.NODE_SIZE, position); - manager.addNode(11, Constants.NODE_SIZE, position); - manager.addNode(12, Constants.NODE_SIZE, position); - manager.addNode(13, Constants.NODE_SIZE, position); - manager.addNode(14, Constants.NODE_SIZE, position); - manager.connectNode(0, 14, 0); - manager.connectNode(14, 13, 0); - manager.connectNode(13, 1, 0); - manager.connectNode(13, 2, 1); - manager.connectNode(13, 3, 2); - manager.connectNode(13, 4, 3); - manager.connectNode(13, 5, 4); - manager.connectNode(1, 6, 0); - manager.connectNode(1, 7, 1); - manager.connectNode(7, 8, 0); - manager.connectNode(8, 9, 0); - manager.connectNode(5, 10, 0); - manager.connectNode(6, 11, 0); - manager.connectNode(6, 12, 1); - - manager.layout(); - - test('All nodes should be positioned symmetrically with respect to their common ancestors', () => { - expect(manager.find(14).getPosition().y).toEqual(manager.find(13).getPosition().y); - expect(manager.find(5).getPosition().y).toEqual(manager.find(10).getPosition().y); - expect(manager.find(11).getPosition().y - manager.find(6).getPosition().y).toEqual( - -(manager.find(12).getPosition().y - manager.find(6).getPosition().y), - ); - expect(manager.find(8).getPosition().y - manager.find(1).getPosition().y).toEqual( - -(manager.find(11).getPosition().y - manager.find(1).getPosition().y), - ); - expect(manager.find(9).getPosition().y - manager.find(1).getPosition().y).toEqual( - -(manager.find(11).getPosition().y - manager.find(1).getPosition().y), - ); - }); - }); - - describe('symmetricDragPredictTest', () => { - const position = { x: 0, y: 0 }; - const manager = new LayoutManager(0, Constants.ROOT_NODE_SIZE); - manager.addNode(1, Constants.NODE_SIZE, position).connectNode(0, 1, 1); - manager.addNode(2, Constants.NODE_SIZE, position).connectNode(1, 2, 0); - manager.layout(); - - test('Prediction A', () => { - const prediction1a = manager.predict(1, 2, { x: -250, y: -20 }); - expect(prediction1a.position.x).toEqual(manager.find(2).getPosition().x); - expect(prediction1a.position.y).toEqual(manager.find(2).getPosition().y); - expect(prediction1a.order).toEqual(manager.find(2).getOrder()); - }); - - test('Prediction B', () => { - const prediction1b = manager.predict(1, 2, { x: -250, y: 20 }); - expect(prediction1b.position.x).toEqual(manager.find(2).getPosition().x); - expect(prediction1b.position.y).toEqual(manager.find(2).getPosition().y); - expect(prediction1b.order).toEqual(manager.find(2).getOrder()); - }); - - test('Prediction C', () => { - const prediction1c = manager.predict(0, 2, { x: -100, y: -20 }); - expect(prediction1c.position.x).toEqual(manager.find(1).getPosition().x); - expect(prediction1c.position.y).toBeLessThan(manager.find(1).getPosition().y); - expect(prediction1c.order).toEqual(manager.find(1).getOrder()); - }); - - test('Prediction D', () => { - const prediction1d = manager.predict(0, 2, { x: -100, y: 20 }); - expect(prediction1d.position.x).toEqual(manager.find(1).getPosition().x); - expect(prediction1d.position.y).toBeGreaterThan(manager.find(1).getPosition().y); - expect(prediction1d.order).toEqual(3); - }); - - test('Prediction E', () => { - const prediction1e = manager.predict(1, 2, { x: -250, y: 0 }); - expect(prediction1e.position.x).toEqual(manager.find(2).getPosition().x); - expect(prediction1e.position.y).toEqual(manager.find(2).getPosition().y); - expect(prediction1e.order).toEqual(manager.find(2).getOrder()); - }); - }); -}); diff --git a/packages/mindplot/tsconfig.json b/packages/mindplot/tsconfig.json index e6134b61..d51ab0bf 100644 --- a/packages/mindplot/tsconfig.json +++ b/packages/mindplot/tsconfig.json @@ -23,7 +23,7 @@ ] }, "include": [ - "src/**/*", "storybook/src/stories", + "src/**/*", "storybook/src/stories", "libraries", ], "exclude": [ "node_modules" diff --git a/packages/mindplot/webpack.common.js b/packages/mindplot/webpack.common.js index 4d5a4706..5d06c033 100644 --- a/packages/mindplot/webpack.common.js +++ b/packages/mindplot/webpack.common.js @@ -15,10 +15,5 @@ const prodConfig = { loader: './src/indexLoader.ts', }, mode: 'production', - resolve: { - alias: { - '@libraries': path.resolve(__dirname, '../../libraries/'), - }, - }, }; module.exports = merge(common, prodConfig); diff --git a/packages/mindplot/webpack.playground.js b/packages/mindplot/webpack.playground.js deleted file mode 100644 index 2565221e..00000000 --- a/packages/mindplot/webpack.playground.js +++ /dev/null @@ -1,38 +0,0 @@ -const path = require('path'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); -const CopyPlugin = require('copy-webpack-plugin'); -const { merge } = require('webpack-merge'); -const common = require('./webpack.common'); - -const playgroundConfig = { - mode: 'development', - entry: { - layout: path.resolve(__dirname, './test/playground/layout/context-loader'), - }, - output: { - path: path.resolve(__dirname, 'test/playground/dist'), - filename: '[name].js', - library: { - type: 'umd', - }, - }, - devServer: { - historyApiFallback: true, - port: 8083, - open: false - }, - plugins: [ - new CopyPlugin({ - patterns: [ - { from: 'test/playground/index.html', to: 'index.html' }, - ], - }), - new HtmlWebpackPlugin({ - chunks: ['layout'], - filename: 'layout.html', - template: 'test/playground/layout/index.html', - }), - ], -}; - -module.exports = merge(common, playgroundConfig); diff --git a/packages/web2d/package.json b/packages/web2d/package.json index 5bffc4a1..fff99b65 100644 --- a/packages/web2d/package.json +++ b/packages/web2d/package.json @@ -4,10 +4,9 @@ "description": "WiseMapping - Web2D Render Library", "homepage": "http://www.wisemapping.org/", "license": "MIT", - "main": "dist/web2d.js", + "main": "src/index.ts", "files": [ - "src", - "dist" + "src" ], "publishConfig": { "registry": "https://registry.yarnpkg.com" @@ -17,6 +16,7 @@ "url": "git@bitbucket.org:wisemapping/wisemapping-frontend.git" }, "scripts": { + "bootstrap": "yalc publish;yalc add @wisemapping/core-js", "dev": "webpack --config webpack.dev.js", "build": "webpack --config webpack.prod.js", "lint": "eslint src", diff --git a/packages/web2d/src/components/Arrow.js b/packages/web2d/src/components/Arrow.ts similarity index 64% rename from packages/web2d/src/components/Arrow.js rename to packages/web2d/src/components/Arrow.ts index 281eeb10..4515d483 100644 --- a/packages/web2d/src/components/Arrow.js +++ b/packages/web2d/src/components/Arrow.ts @@ -16,50 +16,47 @@ * limitations under the License. * */ -import ElementClass from './ElementClass'; +import WorkspaceElement from './WorkspaceElement'; +import ArrowPeer from './peer/svg/ArrowPeer'; +import PositionType from './PositionType'; +import StyleAttributes from './StyleAttributes'; import Toolkit from './Toolkit'; -class Arrow extends ElementClass { - constructor(attributes) { +class Arrow extends WorkspaceElement { + constructor(attributes?: StyleAttributes) { const peer = Toolkit.createArrow(); - const defaultAttributes = { + const defaultAttributes: StyleAttributes = { strokeColor: 'black', strokeWidth: 1, strokeStyle: 'solid', strokeOpacity: 1, }; - for (const key in attributes) { - if (Object.prototype.hasOwnProperty.call(attributes, key)) { - defaultAttributes[key] = attributes[key]; - } - } - - super(peer, defaultAttributes); + const mergedAttr = { ...defaultAttributes, ...attributes }; + super(peer, mergedAttr); } - // eslint-disable-next-line class-methods-use-this - getType() { + getType(): string { return 'Arrow'; } - setFrom(x, y) { + setFrom(x: number, y: number): void { this.peer.setFrom(x, y); } - setControlPoint(point) { + setControlPoint(point: PositionType): void { this.peer.setControlPoint(point); } - setStrokeColor(color) { + setStrokeColor(color: string): void { this.peer.setStrokeColor(color); } - setStrokeWidth(width) { + setStrokeWidth(width: number): void { this.peer.setStrokeWidth(width); } - setDashed(isDashed, length, spacing) { + setDashed(isDashed: boolean, length: number, spacing: number) { this.peer.setDashed(isDashed, length, spacing); } } diff --git a/packages/web2d/src/components/CurvedLine.js b/packages/web2d/src/components/CurvedLine.ts similarity index 68% rename from packages/web2d/src/components/CurvedLine.js rename to packages/web2d/src/components/CurvedLine.ts index cf617896..3ef16816 100644 --- a/packages/web2d/src/components/CurvedLine.js +++ b/packages/web2d/src/components/CurvedLine.ts @@ -16,11 +16,15 @@ * limitations under the License. */ import { $assert } from '@wisemapping/core-js'; -import ElementClass from './ElementClass'; +import WorkspaceElement from './WorkspaceElement'; +import Line from './Line'; +import CurvedLinePeer from './peer/svg/CurvedLinePeer'; +import PositionType from './PositionType'; +import StyleAttributes from './StyleAttributes'; import Toolkit from './Toolkit'; -class CurvedLine extends ElementClass { - constructor(attributes) { +class CurvedLine extends WorkspaceElement implements Line { + constructor(attributes?: StyleAttributes) { const peer = Toolkit.createCurvedLine(); const defaultAttributes = { strokeColor: 'blue', @@ -29,12 +33,8 @@ class CurvedLine extends ElementClass { strokeOpacity: 1, }; - for (const key in attributes) { - if (Object.prototype.hasOwnProperty.call(attributes, key)) { - defaultAttributes[key] = attributes[key]; - } - } - super(peer, defaultAttributes); + const mergedAttr = { ...defaultAttributes, ...attributes }; + super(peer, mergedAttr); } // eslint-disable-next-line class-methods-use-this @@ -42,14 +42,14 @@ class CurvedLine extends ElementClass { return 'CurvedLine'; } - setFrom(x, y) { + setFrom(x: number, y: number): void { $assert(!Number.isNaN(x), 'x must be defined'); $assert(!Number.isNaN(y), 'y must be defined'); this.peer.setFrom(x, y); } - setTo(x, y) { + setTo(x: number, y: number): void { $assert(!Number.isNaN(x), 'x must be defined'); $assert(!Number.isNaN(y), 'y must be defined'); @@ -68,6 +68,10 @@ class CurvedLine extends ElementClass { this.peer.setShowEndArrow(visible); } + getElementClass(): CurvedLine { + return this; + } + isShowEndArrow() { return this.peer.isShowEndArrow(); } @@ -80,15 +84,16 @@ class CurvedLine extends ElementClass { return this.peer.isShowStartArrow(); } - setSrcControlPoint(control) { + setSrcControlPoint(control: PositionType) { this.peer.setSrcControlPoint(control); } - setDestControlPoint(control) { + setDestControlPoint(control: PositionType) { this.peer.setDestControlPoint(control); } - getControlPoints() { + getControlPoints(): [PositionType, PositionType] { + // @ts-ignore return this.peer.getControlPoints(); } @@ -96,31 +101,31 @@ class CurvedLine extends ElementClass { return this.peer.isSrcControlPointCustom(); } - isDestControlPointCustom() { + isDestControlPointCustom(): boolean { return this.peer.isDestControlPointCustom(); } - setIsSrcControlPointCustom(isCustom) { + setIsSrcControlPointCustom(isCustom: boolean) { this.peer.setIsSrcControlPointCustom(isCustom); } - setIsDestControlPointCustom(isCustom) { + setIsDestControlPointCustom(isCustom: boolean) { this.peer.setIsDestControlPointCustom(isCustom); } - updateLine(avoidControlPointFix) { - return this.peer.updateLine(avoidControlPointFix); + updateLine(avoidControlPointFix?: boolean) { + return this.peer.updateLine(Boolean(avoidControlPointFix)); } - setDashed(length, spacing) { + setDashed(length: number, spacing: number) { this.peer.setDashed(length, spacing); } - getWidth() { + getWidth(): number { return this.peer.getWidth(); } - setWidth(value) { + setWidth(value: number): void { this.peer.setWidth(value); } } diff --git a/packages/web2d/src/components/Elipse.js b/packages/web2d/src/components/Ellipse.ts similarity index 58% rename from packages/web2d/src/components/Elipse.js rename to packages/web2d/src/components/Ellipse.ts index f429902e..6d35bedf 100644 --- a/packages/web2d/src/components/Elipse.js +++ b/packages/web2d/src/components/Ellipse.ts @@ -15,12 +15,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import ElementClass from './ElementClass'; +import WorkspaceElement from './WorkspaceElement'; +import ElipsePeer from './peer/svg/ElipsePeer'; +import SizeType from './SizeType'; +import StyleAttributes from './StyleAttributes'; import Toolkit from './Toolkit'; +import PositionType from './PositionType'; -class Elipse extends ElementClass { - constructor(attributes) { - const peer = Toolkit.createElipse(); +class Ellipse extends WorkspaceElement { + constructor(attributes?: StyleAttributes) { + const peer = Toolkit.createEllipse(); const defaultAttributes = { width: 40, height: 40, @@ -29,22 +33,26 @@ class Elipse extends ElementClass { stroke: '1 solid black', fillColor: 'blue', }; - for (const key in attributes) { - if (Object.prototype.hasOwnProperty.call(attributes, key)) { - defaultAttributes[key] = attributes[key]; - } - } - super(peer, defaultAttributes); + + const mergedAttr = { ...defaultAttributes, ...attributes }; + super(peer, mergedAttr); } - // eslint-disable-next-line class-methods-use-this - getType() { - return 'Elipse'; + getType(): string { + return 'Ellipse'; } - getSize() { + getSize(): SizeType { return this.peer.getSize(); } + + getPosition(): PositionType { + return this.peer.getPosition(); + } + + setPosition(x: number, y: number) { + this.peer.setPosition(x, y); + } } -export default Elipse; +export default Ellipse; diff --git a/packages/web2d/src/components/FontStyleType.ts b/packages/web2d/src/components/FontStyleType.ts new file mode 100644 index 00000000..d45aeb10 --- /dev/null +++ b/packages/web2d/src/components/FontStyleType.ts @@ -0,0 +1,18 @@ +/* + * Copyright [2021] [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. + */ +export type FontStyleType = 'italic' | 'normal'; diff --git a/packages/web2d/src/components/FontWeightType.ts b/packages/web2d/src/components/FontWeightType.ts new file mode 100644 index 00000000..48985a14 --- /dev/null +++ b/packages/web2d/src/components/FontWeightType.ts @@ -0,0 +1,18 @@ +/* + * Copyright [2021] [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. + */ +export type FontWeightType = 'bold' | 'normal'; diff --git a/packages/web2d/src/components/Group.js b/packages/web2d/src/components/Group.ts similarity index 78% rename from packages/web2d/src/components/Group.js rename to packages/web2d/src/components/Group.ts index e2433ffa..c8b1f52c 100644 --- a/packages/web2d/src/components/Group.js +++ b/packages/web2d/src/components/Group.ts @@ -18,14 +18,18 @@ */ import { $defined } from '@wisemapping/core-js'; -import ElementClass from './ElementClass'; +import WorkspaceElement from './WorkspaceElement'; +import GroupPeer from './peer/svg/GroupPeer'; +import SizeType from './SizeType'; +import StyleAttributes from './StyleAttributes'; import Toolkit from './Toolkit'; +import PositionType from './PositionType'; /** * A group object can be used to collect shapes. */ -class Group extends ElementClass { - constructor(attributes) { +class Group extends WorkspaceElement { + constructor(attributes?: StyleAttributes) { const peer = Toolkit.createGroup(); const defaultAttributes = { width: 50, @@ -35,19 +39,16 @@ class Group extends ElementClass { coordOrigin: '0 0', coordSize: '50 50', }; - for (const key in attributes) { - if (Object.prototype.hasOwnProperty.call(attributes, key)) { - defaultAttributes[key] = attributes[key]; - } - } - super(peer, defaultAttributes); + + const mergedAttr = { ...defaultAttributes, ...attributes }; + super(peer, mergedAttr); } /** * Remove an element as a child to the object. */ - removeChild(element) { - if (!$defined(element)) { + removeChild(element: WorkspaceElement) { + if (!element) { throw new Error('Child element can not be null'); } @@ -66,8 +67,8 @@ class Group extends ElementClass { /** * Appends an element as a child to the object. */ - append(element) { - if (!$defined(element)) { + append(element: WorkspaceElement) { + if (!element) { throw Error('Child element can not be null'); } @@ -75,7 +76,7 @@ class Group extends ElementClass { throw new Error("It's not posible to add the group as a child of itself"); } - const elementType = element.getType(); + const elementType: string = element.getType(); if (elementType == null) { throw new Error(`It seems not to be an element ->${element}`); } @@ -101,19 +102,19 @@ class Group extends ElementClass { * have no unit specifier - * they are simple numbers, not CSS length quantities. */ - setCoordSize(width, height) { + setCoordSize(width: number, height: number) { this.peer.setCoordSize(width, height); } - setCoordOrigin(x, y) { + setCoordOrigin(x: number, y: number) { this.peer.setCoordOrigin(x, y); } - getCoordOrigin() { + getCoordOrigin(): PositionType { return this.peer.getCoordOrigin(); } - getSize() { + getSize(): SizeType { return this.peer.getSize(); } @@ -141,9 +142,16 @@ class Group extends ElementClass { this.peer._native.append(DomElement); } - setOpacity(value) { + setOpacity(value: number) { this.peer.setOpacity(value); } -} + getPosition(): PositionType { + return this.peer.getPosition(); + } + + setPosition(x: number, y: number) { + this.peer.setPosition(x, y); + } +} export default Group; diff --git a/packages/web2d/src/components/Image.js b/packages/web2d/src/components/Image.ts similarity index 64% rename from packages/web2d/src/components/Image.js rename to packages/web2d/src/components/Image.ts index d5c196dc..7858c79b 100644 --- a/packages/web2d/src/components/Image.js +++ b/packages/web2d/src/components/Image.ts @@ -15,21 +15,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import ElementClass from './ElementClass'; +import WorkspaceElement from './WorkspaceElement'; +import ImagePeer from './peer/svg/ImagePeer'; +import SizeType from './SizeType'; +import StyleAttributes from './StyleAttributes'; import Toolkit from './Toolkit'; +import PositionType from './PositionType'; -class Image extends ElementClass { - constructor(attributes) { +class Image extends WorkspaceElement { + constructor(attributes?: StyleAttributes) { const peer = Toolkit.createImage(); - super(peer, attributes); + super(peer, attributes || {}); } // eslint-disable-next-line class-methods-use-this - getType() { + getType(): string { return 'Image'; } - setHref(href) { + setHref(href: string) { this.peer.setHref(href); } @@ -37,9 +41,17 @@ class Image extends ElementClass { return this.peer.getHref(); } - getSize() { + getSize(): SizeType | undefined { return this.peer.getSize(); } + + getPosition(): PositionType { + return this.peer.getPosition(); + } + + setPosition(x: number, y: number) { + this.peer.setPosition(x, y); + } } export default Image; diff --git a/packages/web2d/src/components/Line.ts b/packages/web2d/src/components/Line.ts new file mode 100644 index 00000000..ce099c68 --- /dev/null +++ b/packages/web2d/src/components/Line.ts @@ -0,0 +1,77 @@ +/* + * Copyright [2021] [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. + */ +import WorkspaceElement from './WorkspaceElement'; +import ElementPeer from './peer/svg/ElementPeer'; +import PositionType from './PositionType'; + +interface Line { + setFrom(x: number, y: number): void; + + setTo(x: number, y: number): void; + + setIsSrcControlPointCustom(value: boolean): void; + + setIsDestControlPointCustom(value: boolean): void; + + setCursor(value: string): void; + + setStroke(width: number, style?: string, color?: string, opacity?: number): void; + + setFill(color: string, opacity: number): void; + + setDashed(v: number, v2: number): void; + + setVisibility(value: boolean, fade?: number): void; + + isVisible(): boolean; + + setOpacity(value: number): void; + + moveToBack(): void; + + setTestId(value: string): void; + + setSrcControlPoint(value: PositionType): void; + + setDestControlPoint(value: PositionType): void; + + isDestControlPointCustom(): boolean; + + isSrcControlPointCustom(): boolean; + + getControlPoints(): [PositionType, PositionType]; + + trigger(value, event): void; + + getTo(): PositionType; + + getFrom(): PositionType; + + moveToFront(): void; + + getType(): string; + + addEvent(value, listener): void; + + removeEvent(value, listener): void; + + updateLine(): void; + + getElementClass(): WorkspaceElement; +} +export default Line; diff --git a/packages/web2d/src/components/Point.js b/packages/web2d/src/components/Point.ts similarity index 65% rename from packages/web2d/src/components/Point.js rename to packages/web2d/src/components/Point.ts index 5fa0ba0f..23da9b09 100644 --- a/packages/web2d/src/components/Point.js +++ b/packages/web2d/src/components/Point.ts @@ -18,12 +18,10 @@ import { $assert } from '@wisemapping/core-js'; class Point { - /** - * @constructs - * @param {Number} x coordinate - * @param {Number} y coordinate - */ - constructor(x, y) { + x: number; + y: number; + + constructor(x: number, y: number) { $assert(typeof x === 'number', `x is not a number: ${x}`); $assert(typeof y === 'number', `x is not a number: ${y}`); @@ -31,29 +29,34 @@ class Point { this.y = y; } - inspect() { + inspect(): string { return `{x:${this.x},y:${this.y}}`; } - clone() { + clone(): Point { return new Point(this.x, this.y); } -} -Point.fromString = function pointFromString(point) { - let result = null; - if (point) { - const values = point.split(','); - if (values.length === 2) { - const x = Number.parseInt(values[0], 10); - const y = Number.parseInt(values[1], 10); + static fromString = (value: string): Point => { + let result: Point | null = null; + if (value) { + const values = value.split(','); + if (values.length === 2) { + const x = Number.parseInt(values[0], 10); + const y = Number.parseInt(values[1], 10); - if (!Number.isNaN(x) && !Number.isNaN(y)) { - result = new Point(x, y); + if (!Number.isNaN(x) && !Number.isNaN(y)) { + result = new Point(x, y); + } } } - } - return result; -}; + + if (!result) { + throw new Error(`String could not be parsed as point${value}`); + } + + return result; + }; +} export default Point; diff --git a/packages/web2d/src/components/PolyLine.js b/packages/web2d/src/components/PolyLine.js deleted file mode 100644 index d0b14301..00000000 --- a/packages/web2d/src/components/PolyLine.js +++ /dev/null @@ -1,69 +0,0 @@ -/* eslint-disable class-methods-use-this */ -/* - * Copyright [2021] [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. - */ -import ElementClass from './ElementClass'; -import Toolkit from './Toolkit'; -import * as PolyLineUtils from './peer/utils/PolyLineUtils'; - -class PolyLine extends ElementClass { - constructor(attributes) { - const peer = Toolkit.createPolyLine(); - const defaultAttributes = { - strokeColor: 'blue', - strokeWidth: 1, - strokeStyle: 'solid', - strokeOpacity: 1, - }; - for (const key in attributes) { - if (Object.prototype.hasOwnProperty.call(attributes, key)) { - defaultAttributes[key] = attributes[key]; - } - } - super(peer, defaultAttributes); - } - - getType() { - return 'PolyLine'; - } - - setFrom(x, y) { - this.peer.setFrom(x, y); - } - - setTo(x, y) { - this.peer.setTo(x, y); - } - - setStyle(style) { - this.peer.setStyle(style); - } - - getStyle() { - return this.peer.getStyle(); - } - - buildCurvedPath(dist, x1, y1, x2, y2) { - return PolyLineUtils.buildCurvedPath(dist, x1, y1, x2, y2); - } - - buildStraightPath(dist, x1, y1, x2, y2) { - return PolyLineUtils.buildStraightPath(dist, x1, y1, x2, y2); - } -} - -export default PolyLine; diff --git a/packages/web2d/src/components/PolyLine.ts b/packages/web2d/src/components/PolyLine.ts new file mode 100644 index 00000000..309946a4 --- /dev/null +++ b/packages/web2d/src/components/PolyLine.ts @@ -0,0 +1,110 @@ +/* eslint-disable class-methods-use-this */ +/* + * Copyright [2021] [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. + */ +import WorkspaceElement from './WorkspaceElement'; +import Toolkit from './Toolkit'; +import * as PolyLineUtils from './peer/utils/PolyLineUtils'; +import Line from './Line'; +import PositionType from './PositionType'; +import StyleAttributes from './StyleAttributes'; +import PolyLinePeer from './peer/svg/PolyLinePeer'; + +class PolyLine extends WorkspaceElement implements Line { + constructor(attributes?: StyleAttributes) { + const peer = Toolkit.createPolyLine(); + const defaultAttributes = { + strokeColor: 'blue', + strokeWidth: 1, + strokeStyle: 'solid', + strokeOpacity: 1, + }; + + const mergedAttr = { ...defaultAttributes, ...attributes }; + super(peer, mergedAttr); + } + + getElementClass(): PolyLine { + return this; + } + + updateLine() { + throw new Error('Method not implemented.'); + } + getTo(): PositionType { + throw new Error('Method not implemented.'); + } + getFrom(): PositionType { + throw new Error('Method not implemented.'); + } + + setIsSrcControlPointCustom(value: boolean): void { + throw new Error('Method not implemented.'); + } + setIsDestControlPointCustom(value: boolean): void { + throw new Error('Method not implemented.'); + } + setDashed(v: number, v2: number): void { + throw new Error('Method not implemented.'); + } + setSrcControlPoint(value: PositionType): void { + throw new Error('Method not implemented.'); + } + setDestControlPoint(value: PositionType): void { + throw new Error('Method not implemented.'); + } + isDestControlPointCustom(): boolean { + throw new Error('Method not implemented.'); + } + isSrcControlPointCustom(): boolean { + throw new Error('Method not implemented.'); + } + + getControlPoints(): [PositionType, PositionType] { + throw new Error('Method not implemented.'); + } + + getType(): string { + return 'PolyLine'; + } + + setFrom(x: number, y: number): void { + this.peer.setFrom(x, y); + } + + setTo(x: number, y: number): void { + this.peer.setTo(x, y); + } + + setStyle(style: string): void { + this.peer.setStyle(style); + } + + getStyle(): string { + return this.peer.getStyle(); + } + + buildCurvedPath(dist: number, x1: number, y1: number, x2: number, y2: number) { + return PolyLineUtils.buildCurvedPath(dist, x1, y1, x2, y2); + } + + buildStraightPath(dist: number, x1: number, y1: number, x2: number, y2: number) { + return PolyLineUtils.buildStraightPath(dist, x1, y1, x2, y2); + } +} + +export default PolyLine; diff --git a/packages/web2d/src/components/PositionType.ts b/packages/web2d/src/components/PositionType.ts new file mode 100644 index 00000000..5a37237c --- /dev/null +++ b/packages/web2d/src/components/PositionType.ts @@ -0,0 +1,20 @@ +/* + * Copyright [2021] [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. + */ +type PositionType = { x: number; y: number }; + +export default PositionType; diff --git a/packages/web2d/src/components/Rect.js b/packages/web2d/src/components/Rect.ts similarity index 73% rename from packages/web2d/src/components/Rect.js rename to packages/web2d/src/components/Rect.ts index 463570c5..7d661390 100644 --- a/packages/web2d/src/components/Rect.js +++ b/packages/web2d/src/components/Rect.ts @@ -16,8 +16,11 @@ * limitations under the License. */ -import ElementClass from './ElementClass'; +import WorkspaceElement from './WorkspaceElement'; +import RectPeer from './peer/svg/RectPeer'; +import StyleAttributes from './StyleAttributes'; import Toolkit from './Toolkit'; +import PositionType from './PositionType'; /** * Create a rectangle and variations of a rectangle shape. @@ -25,8 +28,8 @@ import Toolkit from './Toolkit'; * arc = "" * For rounded rectangles, radius of the ellipse used to round off the corners of the rectangle. */ -class Rect extends ElementClass { - constructor(arc, attributes) { +class Rect extends WorkspaceElement { + constructor(arc: number, attributes?: StyleAttributes) { if (arc && arc > 1) { throw new Error('Arc must be 0<=arc<=1'); } @@ -40,12 +43,8 @@ class Rect extends ElementClass { fillColor: 'green', }; - for (const key in attributes) { - if (Object.prototype.hasOwnProperty.call(attributes, key)) { - defaultAttributes[key] = attributes[key]; - } - } - super(peer, defaultAttributes); + const mergedAttr = { ...defaultAttributes, ...attributes }; + super(peer, mergedAttr); } // eslint-disable-next-line class-methods-use-this @@ -56,6 +55,14 @@ class Rect extends ElementClass { getSize() { return this.peer.getSize(); } + + getPosition(): PositionType { + return this.peer.getPosition(); + } + + setPosition(x: number, y: number) { + this.peer.setPosition(x, y); + } } export default Rect; diff --git a/packages/web2d/src/components/peer/utils/TransformUtils.js b/packages/web2d/src/components/SizeType.ts similarity index 60% rename from packages/web2d/src/components/peer/utils/TransformUtils.js rename to packages/web2d/src/components/SizeType.ts index 96a2b209..c1ce4b86 100644 --- a/packages/web2d/src/components/peer/utils/TransformUtils.js +++ b/packages/web2d/src/components/SizeType.ts @@ -15,22 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -const TransformUtil = { - workoutScale(elementPeer) { - let current = elementPeer.getParent(); - let width = 1; - let height = 1; - while (current) { - const coordSize = current.getCoordSize(); - const size = current.getSize(); - - width *= Number.parseFloat(size.width, 10) / coordSize.width; - height *= Number.parseFloat(size.height, 10) / coordSize.height; - current = current.getParent(); - } - return { width, height }; - }, +type SizeType = { + width: number; + height: number; }; -export default TransformUtil; +export default SizeType; diff --git a/packages/web2d/src/components/StraightLine.js b/packages/web2d/src/components/StraightLine.js deleted file mode 100644 index 19b2cf85..00000000 --- a/packages/web2d/src/components/StraightLine.js +++ /dev/null @@ -1,68 +0,0 @@ -/* eslint-disable class-methods-use-this */ -/* - * Copyright [2021] [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. - */ - -import ElementClass from './ElementClass'; -import Toolkit from './Toolkit'; - -class StraightLine extends ElementClass { - constructor(attributes) { - const peer = Toolkit.createStraightLine(); - const defaultAttributes = { strokeColor: '#495879', strokeWidth: 1, strokeOpacity: 1 }; - for (const key in attributes) { - if (Object.prototype.hasOwnProperty.call(attributes, key)) { - defaultAttributes[key] = attributes[key]; - } - } - super(peer, defaultAttributes); - } - - getType() { - return 'Line'; - } - - setFrom(x, y) { - this.peer.setFrom(x, y); - } - - setTo(x, y) { - this.peer.setTo(x, y); - } - - getFrom() { - return this.peer.getFrom(); - } - - getTo() { - return this.peer.getTo(); - } - - setPosition() { - throw new Error('Unsupported operation'); - } - - setSize() { - throw new Error('Unsupported operation'); - } - - setFill() { - throw new Error('Unsupported operation'); - } -} - -export default StraightLine; diff --git a/packages/web2d/src/components/StraightLine.ts b/packages/web2d/src/components/StraightLine.ts new file mode 100644 index 00000000..808e25fe --- /dev/null +++ b/packages/web2d/src/components/StraightLine.ts @@ -0,0 +1,100 @@ +/* + * Copyright [2021] [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. + */ + +import WorkspaceElement from './WorkspaceElement'; +import Line from './Line'; +import StraightLinePeer from './peer/svg/StraightPeer'; +import PositionType from './PositionType'; +import StyleAttributes from './StyleAttributes'; +import Toolkit from './Toolkit'; + +class StraightLine extends WorkspaceElement implements Line { + constructor(attributes?: StyleAttributes) { + const peer = Toolkit.createStraightLine(); + const defaultAttributes = { strokeColor: '#495879', strokeWidth: 1, strokeOpacity: 1 }; + + const mergedAttr = { ...defaultAttributes, ...attributes }; + super(peer, mergedAttr); + } + + getElementClass(): StraightLine { + return this; + } + + updateLine() { + throw new Error('Method not implemented.'); + } + setIsSrcControlPointCustom(value: boolean): void { + throw new Error('Method not implemented.'); + } + setIsDestControlPointCustom(value: boolean): void { + throw new Error('Method not implemented.'); + } + setDashed(v: number, v2: number): void { + throw new Error('Method not implemented.'); + } + setSrcControlPoint(value: PositionType): void { + throw new Error('Method not implemented.'); + } + setDestControlPoint(value: PositionType): void { + throw new Error('Method not implemented.'); + } + isDestControlPointCustom(): boolean { + throw new Error('Method not implemented.'); + } + isSrcControlPointCustom(): boolean { + throw new Error('Method not implemented.'); + } + getControlPoints(): [PositionType, PositionType] { + throw new Error('Method not implemented.'); + } + + getType() { + return 'Line'; + } + + setFrom(x: number, y: number) { + this.peer.setFrom(x, y); + } + + setTo(x: number, y: number) { + this.peer.setTo(x, y); + } + + getFrom(): PositionType { + return this.peer.getFrom(); + } + + getTo(): PositionType { + return this.peer.getTo(); + } + + setPosition() { + throw new Error('Unsupported operation'); + } + + setSize(x: number, y: number) { + throw new Error('Unsupported operation'); + } + + setFill(color: string, opacity: number) { + throw new Error('Unsupported operation'); + } +} + +export default StraightLine; diff --git a/packages/web2d/src/components/StyleAttributes.ts b/packages/web2d/src/components/StyleAttributes.ts new file mode 100644 index 00000000..029b5ba9 --- /dev/null +++ b/packages/web2d/src/components/StyleAttributes.ts @@ -0,0 +1,38 @@ +/* + * Copyright [2021] [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. + */ + +type StyleAttributes = { + width?: number | string; + height?: number | string; + x?: number; + y?: number; + stroke?: string; + fillColor?: string; + fillOpacity?: string; + opacity?: number; + strokeColor?: string; + strokeWidth?: number; + strokeStyle?: string; + strokeOpacity?: number; + visibility?: boolean; + coordSizeHeight?: number; + coordSizeWidth?: number; + coordOriginY?: number; + coordOriginX?: number; +}; +export default StyleAttributes; diff --git a/packages/web2d/src/components/Text.js b/packages/web2d/src/components/Text.ts similarity index 55% rename from packages/web2d/src/components/Text.js rename to packages/web2d/src/components/Text.ts index 58fa20df..d41dcfe7 100644 --- a/packages/web2d/src/components/Text.js +++ b/packages/web2d/src/components/Text.ts @@ -17,86 +17,99 @@ */ import { $assert } from '@wisemapping/core-js'; -import ElementClass from './ElementClass'; +import WorkspaceElement from './WorkspaceElement'; +import { FontWeightType } from './FontWeightType'; +import TextPeer from './peer/svg/TextPeer'; import TransformUtil from './peer/utils/TransformUtils'; +import StyleAttributes from './StyleAttributes'; import Toolkit from './Toolkit'; +import PositionType from './PositionType'; +import { FontStyle } from './peer/svg/FontPeer'; -class Text extends ElementClass { - constructor(attributes) { +class Text extends WorkspaceElement { + constructor(attributes?: StyleAttributes) { const peer = Toolkit.createText('Arial'); + // @ts-ignore super(peer, attributes); } - // eslint-disable-next-line class-methods-use-this - getType() { + getType(): string { return 'Text'; } - setText(text) { + setText(text: string): void { this.peer.setText(text); } - setTextAlignment(align) { + setTextAlignment(align: string) { $assert(align, 'align can not be null'); this.peer.setTextAlignment(align); } - setTextSize(width, height) { - this.peer.setContentSize(width, height); - } - - getText() { + getText(): string { return this.peer.getText(); } - setFont(font, size, style, weight) { + setFont(font: string, size: number, style: string, weight: string): void { this.peer.setFont(font, size, style, weight); } - setFontName(fontName) { + setFontName(fontName: string): void { this.peer.setFontName(fontName); } - setColor(color) { + setColor(color: string): void { this.peer.setColor(color); } - getColor() { + getColor(): string | null { return this.peer.getColor(); } - setStyle(style) { + setStyle(style: string): void { this.peer.setStyle(style); } - setWeight(weight) { + setWeight(weight: FontWeightType): void { this.peer.setWeight(weight); } - getFontStyle() { + setFontSize(size: number): void { + this.peer.setFontSize(size); + } + + getFontStyle(): FontStyle { return this.peer.getFontStyle(); } - setSize(size) { - this.peer.setSize(size); - } - - getHtmlFontSize() { + getHtmlFontSize(): string { const scale = TransformUtil.workoutScale(this.peer); return this.peer.getHtmlFontSize(scale); } - getWidth() { - return this.peer.getWidth(); + getShapeWidth(): number { + return this.peer.getShapeWidth(); } - getHeight() { - return Number.parseInt(this.peer.getHeight(), 10); + getShapeHeight(): number { + return this.peer.getShapeHeight(); } - getFontHeight() { + getFontHeight(): number { const lines = this.peer.getText().split('\n').length; - return Math.round(this.getHeight() / lines); + return this.getShapeHeight() / lines; + } + + getPosition(): PositionType { + return this.peer.getPosition(); + } + + setPosition(x: number, y: number) { + this.peer.setPosition(x, y); + } + + getNativePosition() { + return this.peer.getNativePosition(); } } diff --git a/packages/web2d/src/components/Toolkit.js b/packages/web2d/src/components/Toolkit.ts similarity index 76% rename from packages/web2d/src/components/Toolkit.js rename to packages/web2d/src/components/Toolkit.ts index e61c513b..efb47a2b 100644 --- a/packages/web2d/src/components/Toolkit.js +++ b/packages/web2d/src/components/Toolkit.ts @@ -18,7 +18,7 @@ import FontPeer from './peer/svg/FontPeer'; import WorkspacePeer from './peer/svg/WorkspacePeer'; import GroupPeer from './peer/svg/GroupPeer'; -import ElipsePeer from './peer/svg/ElipsePeer'; +import EllipsePeer from './peer/svg/ElipsePeer'; import StraightLinePeer from './peer/svg/StraightPeer'; import PolyLinePeer from './peer/svg/PolyLinePeer'; import CurvedLinePeer from './peer/svg/CurvedLinePeer'; @@ -28,27 +28,27 @@ import ImagePeer from './peer/svg/ImagePeer'; import RectPeer from './peer/svg/RectPeer'; class Toolkit { - static createWorkspace(element) { - return new WorkspacePeer(element); + static createWorkspace(element?: HTMLElement) { + return new WorkspacePeer(); } - static createGroup() { + static createGroup(): GroupPeer { return new GroupPeer(); } - static createElipse() { - return new ElipsePeer(); + static createEllipse(): EllipsePeer { + return new EllipsePeer(); } - static createStraightLine() { + static createStraightLine(): StraightLinePeer { return new StraightLinePeer(); } - static createPolyLine() { + static createPolyLine(): PolyLinePeer { return new PolyLinePeer(); } - static createCurvedLine() { + static createCurvedLine(): CurvedLinePeer { return new CurvedLinePeer(); } @@ -56,16 +56,16 @@ class Toolkit { return new ArrowPeer(); } - static createText(fontName) { + static createText(fontName: string): TextPeer { const font = new FontPeer(fontName); return new TextPeer(font); } - static createImage() { + static createImage(): ImagePeer { return new ImagePeer(); } - static createRect(arc) { + static createRect(arc: number): RectPeer { return new RectPeer(arc); } } diff --git a/packages/web2d/src/components/Workspace.js b/packages/web2d/src/components/Workspace.ts similarity index 71% rename from packages/web2d/src/components/Workspace.js rename to packages/web2d/src/components/Workspace.ts index fca519bf..474b4aa8 100644 --- a/packages/web2d/src/components/Workspace.js +++ b/packages/web2d/src/components/Workspace.ts @@ -16,46 +16,50 @@ * limitations under the License. */ import { $defined } from '@wisemapping/core-js'; -import ElementClass from './ElementClass'; +import WorkspaceElement from './WorkspaceElement'; +import WorkspacePeer from './peer/svg/WorkspacePeer'; +import PositionType from './PositionType'; +import StyleAttributes from './StyleAttributes'; import Toolkit from './Toolkit'; -class Workspace extends ElementClass { - constructor(attributes) { +class Workspace extends WorkspaceElement { + private _htmlContainer: HTMLElement; + + constructor(attributes?: StyleAttributes) { const htmlContainer = Workspace._createDivContainer(); const peer = Toolkit.createWorkspace(htmlContainer); - const defaultAttributes = { - width: '200px', - height: '200px', + const defaultAttributes: StyleAttributes = { + width: '400px', + height: '400px', stroke: '1px solid #edf1be', fillColor: 'white', - coordOrigin: '0 0', - coordSize: '200 200', + coordOriginX: 0, + coordOriginY: 0, + coordSizeWidth: 200, + coordSizeHeight: 200, }; - for (const key in attributes) { - if (Object.prototype.hasOwnProperty.call(attributes, key)) { - defaultAttributes[key] = attributes[key]; - } - } - super(peer, defaultAttributes, true); + + const mergedAttr = { ...defaultAttributes, ...attributes }; + super(peer, mergedAttr, true); + this._htmlContainer = htmlContainer; - this._initialize(defaultAttributes); + this._initialize(mergedAttr); htmlContainer.append(this.peer._native); } - // eslint-disable-next-line class-methods-use-this - getType() { + getType(): string { return 'Workspace'; } /** * Appends an element as a child to the object. */ - append(element) { - if (!$defined(element)) { + append(element: WorkspaceElement) { + if (!element) { throw new Error('Child element can not be null'); } const elementType = element.getType(); - if (elementType == null) { + if (!elementType) { throw new Error(`It seems not to be an element ->${element}`); } @@ -66,7 +70,7 @@ class Workspace extends ElementClass { this.peer.append(element.peer); } - addItAsChildTo(element) { + addItAsChildTo(element: JQuery) { if (!$defined(element)) { throw new Error('Workspace div container can not be null'); } @@ -76,7 +80,7 @@ class Workspace extends ElementClass { /** * Create a new div element that will be responsible for containing the workspace elements. */ - static _createDivContainer() { + static _createDivContainer(): HTMLElement { const container = window.document.createElement('div'); container.style.position = 'relative'; container.style.top = '0px'; @@ -95,16 +99,16 @@ class Workspace extends ElementClass { * pt (points; 1pt=1/72in) * pc (picas; 1pc=12pt) */ - setSize(width, height) { + setSize(width: string | number, height: string | number) { // HTML container must have the size of the group element. - if ($defined(width)) { - this._htmlContainer.style.width = width; + if (width) { + this._htmlContainer.style.width = String(width); } - if ($defined(height)) { - this._htmlContainer.style.height = height; + if (height) { + this._htmlContainer.style.height = String(height); } - this.peer.setSize(width, height); + this.peer.setSize(Number.parseInt(String(width)), Number.parseInt(String(height))); } /** @@ -117,21 +121,18 @@ class Workspace extends ElementClass { * and so on) have no unit specifier - * they are simple numbers, not CSS length quantities. */ - setCoordSize(width, height) { - this.peer.setCoordSize(parseInt(width, 10), parseInt(height, 10)); + setCoordSize(width: number | string, height: number | string): void { + this.peer.setCoordSize(Number.parseInt(String(width), 10), Number.parseInt(String(height), 10)); } - /** - * @Todo: Complete Doc - */ - setCoordOrigin(x, y) { + setCoordOrigin(x: number, y: number): void { this.peer.setCoordOrigin(x, y); } /** * @Todo: Complete Doc */ - getCoordOrigin() { + getCoordOrigin(): PositionType { return this.peer.getCoordOrigin(); } @@ -143,24 +144,19 @@ class Workspace extends ElementClass { return this._htmlContainer; } - setFill(color, opacity) { + setFill(color: string, opacity: number) { this._htmlContainer.style.backgroundColor = color; if (opacity || opacity === 0) { throw new Error('Unsupported operation. Opacity not supported.'); } } - getFill() { - const color = this._htmlContainer.style.backgroundColor; - return { color }; - } - getSize() { const { width, height } = this._htmlContainer.style; return { width, height }; } - setStroke(width, style, color, opacity) { + setStroke(width: number, style: string, color: string, opacity: number) { if (style !== 'solid') { throw new Error(`Not supported style stroke style:${style}`); } @@ -171,15 +167,15 @@ class Workspace extends ElementClass { } } - getCoordSize() { + getCoordSize(): { width: number; height: number } { return this.peer.getCoordSize(); } /** * Remove an element as a child to the object. */ - removeChild(element) { - if (!$defined(element)) { + removeChild(element: WorkspaceElement): void { + if (!element) { throw new Error('Child element can not be null'); } @@ -195,8 +191,8 @@ class Workspace extends ElementClass { this.peer.removeChild(element.peer); } - getSVGElement() { - return this._htmlContainer.firstChild; + getSVGElement(): Element { + return this._htmlContainer.firstChild as Element; } } diff --git a/packages/web2d/src/components/ElementClass.js b/packages/web2d/src/components/WorkspaceElement.ts similarity index 69% rename from packages/web2d/src/components/ElementClass.js rename to packages/web2d/src/components/WorkspaceElement.ts index 409f2c7c..0c1a5bb7 100644 --- a/packages/web2d/src/components/ElementClass.js +++ b/packages/web2d/src/components/WorkspaceElement.ts @@ -17,22 +17,24 @@ */ import { $defined } from '@wisemapping/core-js'; +import ElementPeer from './peer/svg/ElementPeer'; +import StyleAttributes from './StyleAttributes'; -class ElementClass { - constructor(peer, attributes, delayInit) { +abstract class WorkspaceElement { + peer: T; + + constructor(peer: T, attributes: StyleAttributes, delayInit?: boolean) { this.peer = peer; if (peer == null) { throw new Error('Element peer can not be null'); } - if (!delayInit) { - if ($defined(attributes)) { - this._initialize(attributes); - } + if (!delayInit && attributes) { + this._initialize(attributes); } } - _initialize(attributes) { + protected _initialize(attributes: StyleAttributes) { const batchExecute = {}; // Collect arguments ... @@ -44,10 +46,10 @@ class ElementClass { funcArgs = []; } - const signature = Element._propertyNameToSignature[key]; + const signature = WorkspaceElement._propertyNameToSignature[key]; const argPositions = signature[1]; - if (argPositions !== Element._SIGNATURE_MULTIPLE_ARGUMENTS) { + if (argPositions !== WorkspaceElement._SIGNATURE_MULTIPLE_ARGUMENTS) { funcArgs[argPositions] = attributes[key]; } else { funcArgs = attributes[key].split(' '); @@ -60,21 +62,17 @@ class ElementClass { // eslint-disable-next-line guard-for-in for (const key in batchExecute) { const func = this[key]; - if (!$defined(func)) { + if (!func) { throw new Error(`Could not find function: ${key}`); } func.apply(this, batchExecute[key]); } } - setSize(width, height) { + setSize(width: number, height: number) { this.peer.setSize(width, height); } - setPosition(cx, cy) { - this.peer.setPosition(cx, cy); - } - /** * Allows the registration of event listeners on the event target. * type @@ -87,17 +85,17 @@ class ElementClass { * The following events types are supported: * */ - addEvent(type, listener) { + addEvent(type: string, listener) { this.peer.addEvent(type, listener); } - trigger(type, event) { + trigger(type: string, event) { this.peer.trigger(type, event); } - cloneEvents(from) { - this.peer.cloneEvents(from); - } + // cloneEvents(from) { + // this.peer.cloneEvents(from); + // } /** * @@ -112,7 +110,7 @@ class ElementClass { * This interace will be invoked passing an event as argument and * the 'this' referece in the function will be the element. */ - removeEvent(type, listener) { + removeEvent(type: string, listener) { this.peer.removeEvent(type, listener); } @@ -120,12 +118,7 @@ class ElementClass { * /* * Returns element type name. */ - // eslint-disable-next-line class-methods-use-this - getType() { - throw new Error( - 'Not implemeneted yet. This method must be implemented by all the inherited objects.', - ); - } + abstract getType(): string; /** * Todo: Doc @@ -139,18 +132,10 @@ class ElementClass { * color: Fill color * opacity: Opacity of the fill. It must be less than 1. */ - setFill(color, opacity) { + setFill(color: string, opacity?: number): void { this.peer.setFill(color, opacity); } - getPosition() { - return this.peer.getPosition(); - } - - getNativePosition() { - return this.peer.getNativePosition(); - } - /* * Defines the element stroke properties. * width: stroke width @@ -158,7 +143,7 @@ class ElementClass { * color: stroke color * opacity: stroke visibility */ - setStroke(width, style, color, opacity) { + setStroke(width: number, style: string, color?: string, opacity?: number) { if ( style != null && style !== undefined && @@ -175,7 +160,7 @@ class ElementClass { // eslint-disable-next-line class-methods-use-this _attributeNameToFuncName(attributeKey, prefix) { - const signature = Element._propertyNameToSignature[attributeKey]; + const signature = WorkspaceElement._propertyNameToSignature[attributeKey]; if (!$defined(signature)) { throw new Error(`Unsupported attribute: ${attributeKey}`); } @@ -192,18 +177,18 @@ class ElementClass { * fill, fillColor, fillOpacity, coordSize, coordSizeWidth, coordSizeHeight, * coordOrigin, coordOriginX, coordOrigiY */ - setAttribute(key, value) { + setAttribute(key: string, value: string | number) { const funcName = this._attributeNameToFuncName(key, 'set'); - const signature = Element._propertyNameToSignature[key]; + const signature = WorkspaceElement._propertyNameToSignature[key]; if (signature == null) { throw new Error(`Could not find the signature for:${key}`); } // Parse arguments .. const argPositions = signature[1]; - let args = []; - if (argPositions !== this._SIGNATURE_MULTIPLE_ARGUMENTS) { + let args: (string | number)[] = []; + if (argPositions !== WorkspaceElement._SIGNATURE_MULTIPLE_ARGUMENTS) { args[argPositions] = value; } else { const strValue = String(value); @@ -218,10 +203,10 @@ class ElementClass { setter.apply(this, args); } - getAttribute(key) { + getAttribute(key: string) { const funcName = this._attributeNameToFuncName(key, 'get'); - const signature = Element._propertyNameToSignature[key]; + const signature = WorkspaceElement._propertyNameToSignature[key]; if (signature == null) { throw new Error(`Could not find the signature for:${key}`); } @@ -250,30 +235,30 @@ class ElementClass { * Parameters: * opacity: A value between 0 and 1. */ - setOpacity(opacity) { + setOpacity(opacity: number): void { this.peer.setStroke(null, null, null, opacity); this.peer.setFill(null, opacity); } - setVisibility(value, fade) { + setVisibility(value: boolean, fade?: number): void { this.peer.setVisibility(value, fade); } - isVisible() { + isVisible(): boolean { return this.peer.isVisible(); } /** * Move the element to the front */ - moveToFront() { + moveToFront(): void { this.peer.moveToFront(); } /** * Move the element to the back */ - moveToBack() { + moveToBack(): void { this.peer.moveToBack(); } @@ -281,59 +266,55 @@ class ElementClass { return this.peer.getStroke(); } - setCursor(type) { + setCursor(type: string) { this.peer.setCursor(type); } - getParent() { - return this.peer.getParent(); - } - - setTestId(testId) { + setTestId(testId: string) { this.peer._native.setAttribute('test-id', testId); } + + static _SIGNATURE_MULTIPLE_ARGUMENTS = -1; + static _supportedEvents = [ + 'click', + 'dblclick', + 'mousemove', + 'mouseout', + 'mouseover', + 'mousedown', + 'mouseup', + ]; + + private static _propertyNameToSignature = { + // Format: [attribute name, argument position on setter, attribute name on getter] + size: ['size', -1], + width: ['size', 0, 'width'], + height: ['size', 1, 'height'], + + position: ['position', -1], + x: ['position', 0, 'x'], + y: ['position', 1, 'y'], + + stroke: ['stroke', -1], + strokeWidth: ['stroke', 0, 'width'], + strokeStyle: ['stroke', 1, 'style'], + strokeColor: ['stroke', 2, 'color'], + strokeOpacity: ['stroke', 3, 'opacity'], + + fill: ['fill', -1], + fillColor: ['fill', 0, 'color'], + fillOpacity: ['fill', 1, 'opacity'], + + coordSize: ['coordSize', -1], + coordSizeWidth: ['coordSize', 0, 'width'], + coordSizeHeight: ['coordSize', 1, 'height'], + + coordOrigin: ['coordOrigin', -1], + coordOriginX: ['coordOrigin', 0, 'x'], + coordOriginY: ['coordOrigin', 1, 'y'], + + visibility: ['visibility', 0], + opacity: ['opacity', 0], + }; } - -Element._SIGNATURE_MULTIPLE_ARGUMENTS = -1; -Element._supportedEvents = [ - 'click', - 'dblclick', - 'mousemove', - 'mouseout', - 'mouseover', - 'mousedown', - 'mouseup', -]; -Element._propertyNameToSignature = { - // Format: [attribute name, argument position on setter, attribute name on getter] - size: ['size', -1], - width: ['size', 0, 'width'], - height: ['size', 1, 'height'], - - position: ['position', -1], - x: ['position', 0, 'x'], - y: ['position', 1, 'y'], - - stroke: ['stroke', -1], - strokeWidth: ['stroke', 0, 'width'], - strokeStyle: ['stroke', 1, 'style'], - strokeColor: ['stroke', 2, 'color'], - strokeOpacity: ['stroke', 3, 'opacity'], - - fill: ['fill', -1], - fillColor: ['fill', 0, 'color'], - fillOpacity: ['fill', 1, 'opacity'], - - coordSize: ['coordSize', -1], - coordSizeWidth: ['coordSize', 0, 'width'], - coordSizeHeight: ['coordSize', 1, 'height'], - - coordOrigin: ['coordOrigin', -1], - coordOriginX: ['coordOrigin', 0, 'x'], - coordOriginY: ['coordOrigin', 1, 'y'], - - visibility: ['visibility', 0], - opacity: ['opacity', 0], -}; - -export default ElementClass; +export default WorkspaceElement; diff --git a/packages/web2d/src/components/peer/svg/ArrowPeer.js b/packages/web2d/src/components/peer/svg/ArrowPeer.ts similarity index 76% rename from packages/web2d/src/components/peer/svg/ArrowPeer.js rename to packages/web2d/src/components/peer/svg/ArrowPeer.ts index aa678074..4602bd1f 100644 --- a/packages/web2d/src/components/peer/svg/ArrowPeer.js +++ b/packages/web2d/src/components/peer/svg/ArrowPeer.ts @@ -17,35 +17,39 @@ */ import { $defined } from '@wisemapping/core-js'; +import PositionType from '../../PositionType'; import ElementPeer from './ElementPeer'; -import Point from '../../Point'; class ArrowPeer extends ElementPeer { + private _fromPoint: PositionType; + private _controlPoint: PositionType | null; + constructor() { - const svgElement = window.document.createElementNS(ElementPeer.svgNamespace, 'path'); + const svgElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'path'); super(svgElement); - this._style = {}; + this._fromPoint = { x: 0, y: 0 }; + this._controlPoint = null; } - setFrom(x, y) { - this._fromPoint = new Point(x, y); + setFrom(x: number, y: number) { + this._fromPoint = { x, y }; this._redraw(); } - setControlPoint(point) { + setControlPoint(point: PositionType) { this._controlPoint = point; this._redraw(); } - setStrokeColor(color) { - this.setStroke(null, null, color, null); + setStrokeColor(color: string) { + this.setStroke(null, null, color); } - setStrokeWidth(width) { + setStrokeWidth(width: number) { this.setStroke(width); } - setDashed(isDashed, length, spacing) { + setDashed(isDashed: boolean, length: number, spacing: number) { if ($defined(isDashed) && isDashed && $defined(length) && $defined(spacing)) { this._native.setAttribute('stroke-dasharray', `${length}${spacing}`); } else { @@ -53,21 +57,11 @@ class ArrowPeer extends ElementPeer { } } - _updateStyle() { - let style = ''; - for (const key in this._style) { - if (Object.prototype.hasOwnProperty.call(this._style, key)) { - style += `${key}:${this._style[key]} `; - } - } - this._native.setAttribute('style', style); - } - - _redraw() { - let x; - let y; - let xp; - let yp; + private _redraw() { + let x: number; + let y: number; + let xp: number; + let yp: number; if (this._fromPoint && this._controlPoint) { if (this._controlPoint.y === 0) this._controlPoint.y = 1; @@ -92,7 +86,8 @@ class ArrowPeer extends ElementPeer { const path = `M${this._fromPoint.x},${this._fromPoint.y} ` + - `L${x + this._fromPoint.x},${y + this._fromPoint.y} M${this._fromPoint.x},${this._fromPoint.y + `L${x + this._fromPoint.x},${y + this._fromPoint.y} M${this._fromPoint.x},${ + this._fromPoint.y } ` + `L${xp + this._fromPoint.x},${yp + this._fromPoint.y}`; this._native.setAttribute('d', path); diff --git a/packages/web2d/src/components/peer/svg/CurvedLinePeer.js b/packages/web2d/src/components/peer/svg/CurvedLinePeer.ts similarity index 59% rename from packages/web2d/src/components/peer/svg/CurvedLinePeer.js rename to packages/web2d/src/components/peer/svg/CurvedLinePeer.ts index 18696dd0..48ba36a0 100644 --- a/packages/web2d/src/components/peer/svg/CurvedLinePeer.js +++ b/packages/web2d/src/components/peer/svg/CurvedLinePeer.ts @@ -16,21 +16,39 @@ * limitations under the License. */ import { $defined } from '@wisemapping/core-js'; +import PositionType from '../../PositionType'; import ElementPeer from './ElementPeer'; -import Point from '../../Point'; class CurvedLinePeer extends ElementPeer { + private _customControlPoint_1: boolean; + private _customControlPoint_2: boolean; + private _control1: PositionType; + private _control2: PositionType; + private _x1: number; + private _y1: number; + private _x2: number; + private _y2: number; + private _showEndArrow: boolean; + private _showStartArrow: boolean; + private _width: any; + constructor() { - const svgElement = window.document.createElementNS(ElementPeer.svgNamespace, 'path'); + const svgElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'path'); super(svgElement); this._customControlPoint_1 = false; this._customControlPoint_2 = false; - this._control1 = new Point(0, 0); - this._control2 = new Point(0, 0); + this._control1 = { x: 0, y: 0 }; + this._control2 = { x: 0, y: 0 }; this.setWidth(1); + this._showEndArrow = false; + this._showStartArrow = false; + this._x1 = 0; + this._x2 = 0; + this._y1 = 0; + this._y2 = 0; } - setSrcControlPoint(control) { + setSrcControlPoint(control: PositionType): void { this._customControlPoint_1 = true; const change = this._control1.x !== control.x || this._control1.y !== control.y; if (control) { @@ -41,7 +59,7 @@ class CurvedLinePeer extends ElementPeer { } } - setDestControlPoint(control) { + setDestControlPoint(control: PositionType): void { this._customControlPoint_2 = true; const change = this._control2.x !== control.x || this._control2.y !== control.y; if (control) { @@ -52,109 +70,125 @@ class CurvedLinePeer extends ElementPeer { } } - isSrcControlPointCustom() { + isSrcControlPointCustom(): boolean { return this._customControlPoint_1; } - isDestControlPointCustom() { + isDestControlPointCustom(): boolean { return this._customControlPoint_2; } - setIsSrcControlPointCustom(isCustom) { - this._customControlPoint_1 = isCustom; + setIsSrcControlPointCustom(value: boolean): void { + this._customControlPoint_1 = value; } - setIsDestControlPointCustom(isCustom) { - this._customControlPoint_2 = isCustom; + setIsDestControlPointCustom(value: boolean): void { + this._customControlPoint_2 = value; } - getControlPoints() { + getControlPoints(): [PositionType, PositionType] { return [{ ...this._control1 }, { ...this._control2 }]; } - setFrom(x1, y1) { + setFrom(x1: number, y1: number): void { const change = this._x1 !== x1 || this._y1 !== y1; this._x1 = x1; this._y1 = y1; - if (change) { this._updatePath(); } + if (change) { + this._updatePath(); + } } - setTo(x2, y2) { + setTo(x2: number, y2: number) { const change = this._x2 !== x2 || this._y2 !== y2; this._x2 = x2; this._y2 = y2; if (change) this._updatePath(); } - getFrom() { - return new Point(this._x1, this._y1); + getFrom(): PositionType { + return { x: this._x1, y: this._y1 }; } - getTo() { - return new Point(this._x2, this._y2); + getTo(): PositionType { + return { x: this._x2, y: this._y2 }; } - setStrokeWidth(width) { - this._native.setAttribute('stroke-width', width); + setStrokeWidth(width: number): void { + this._native.setAttribute('stroke-width', String(width)); } - updateLine(avoidControlPointFix) { + updateLine(avoidControlPointFix: boolean) { this._updatePath(avoidControlPointFix); } - setShowEndArrow(visible) { + setShowEndArrow(visible: boolean): void { this._showEndArrow = visible; - this.updateLine(); + this._updatePath(); } - isShowEndArrow() { + isShowEndArrow(): boolean { return this._showEndArrow; } - setShowStartArrow(visible) { + setShowStartArrow(visible: boolean): void { this._showStartArrow = visible; - this.updateLine(); + this._updatePath(); } isShowStartArrow() { return this._showStartArrow; } - getWidth() { + getWidth(): number { return this._width; } - setWidth(value) { + setWidth(value: number) { this._width = value; if (this._width === 1) { this.setFill('none'); } - this.updateLine(); + this._updatePath(); } - _updatePath(avoidControlPointFix) { + private _updatePath(avoidControlPointFix?: boolean) { if ($defined(this._x1) && $defined(this._y1) && $defined(this._x2) && $defined(this._y2)) { this._calculateAutoControlPoints(avoidControlPointFix); const moveTo = CurvedLinePeer._pointToStr(this._x1, this._y1 - this.getWidth() / 2); - const curveP1 = CurvedLinePeer._pointToStr(this._control1.x + this._x1, this._control1.y + this._y1); - const curveP2 = CurvedLinePeer._pointToStr(this._control2.x + this._x2, this._control2.y + this._y2); + const curveP1 = CurvedLinePeer._pointToStr( + this._control1.x + this._x1, + this._control1.y + this._y1, + ); + const curveP2 = CurvedLinePeer._pointToStr( + this._control2.x + this._x2, + this._control2.y + this._y2, + ); const curveP3 = CurvedLinePeer._pointToStr(this._x2, this._y2); - const curveP4 = CurvedLinePeer._pointToStr(this._control2.x + this._x2, this._control2.y + this._y2 + this.getWidth() * 0.4); - const curveP5 = CurvedLinePeer._pointToStr(this._control1.x + this._x1, this._control1.y + this._y1 + this.getWidth() * 0.7); + const curveP4 = CurvedLinePeer._pointToStr( + this._control2.x + this._x2, + this._control2.y + this._y2 + this.getWidth() * 0.4, + ); + const curveP5 = CurvedLinePeer._pointToStr( + this._control1.x + this._x1, + this._control1.y + this._y1 + this.getWidth() * 0.7, + ); const curveP6 = CurvedLinePeer._pointToStr(this._x1, this._y1 + this.getWidth() / 2); - const path = `M${moveTo} C${curveP1} ${curveP2} ${curveP3} ${this.getWidth() > 1 ? ` ${curveP4} ${curveP5} ${curveP6} Z` : ''}`; + const path = `M${moveTo} C${curveP1} ${curveP2} ${curveP3} ${ + this.getWidth() > 1 ? ` ${curveP4} ${curveP5} ${curveP6} Z` : '' + }`; this._native.setAttribute('d', path); } } - static _pointToStr(x, y) { + private static _pointToStr(x: number, y: number) { return `${x.toFixed(1)},${y.toFixed(1)} `; } - static _calculateDefaultControlPoints(srcPos, tarPos) { + private static _calculateDefaultControlPoints(srcPos: PositionType, tarPos: PositionType) { const y = srcPos.y - tarPos.y; const x = srcPos.x - tarPos.x; const div = Math.abs(x) > 0.1 ? x : 0.1; // Prevent division by 0. @@ -171,14 +205,17 @@ class CurvedLinePeer extends ElementPeer { const x2 = tarPos.x + Math.sqrt((l * l) / (1 + m * m)) * fix * -1; const y2 = m * (x2 - tarPos.x) + tarPos.y; - return [new Point(-srcPos.x + x1, -srcPos.y + y1), new Point(-tarPos.x + x2, -tarPos.y + y2)]; + return [ + { x: -srcPos.x + x1, y: -srcPos.y + y1 }, + { x: -tarPos.x + x2, y: -tarPos.y + y2 }, + ]; } - _calculateAutoControlPoints(avoidControlPointFix) { + private _calculateAutoControlPoints(avoidControlPointFix) { // Both points available, calculate real points const defaultpoints = CurvedLinePeer._calculateDefaultControlPoints( - new Point(this._x1, this._y1), - new Point(this._x2, this._y2), + { x: this._x1, y: this._y1 }, + { x: this._x2, y: this._y2 }, ); if ( !this._customControlPoint_1 && diff --git a/packages/web2d/src/components/peer/svg/ElementPeer.js b/packages/web2d/src/components/peer/svg/ElementPeer.ts similarity index 71% rename from packages/web2d/src/components/peer/svg/ElementPeer.js rename to packages/web2d/src/components/peer/svg/ElementPeer.ts index 969c8c02..cd0d5ff8 100644 --- a/packages/web2d/src/components/peer/svg/ElementPeer.js +++ b/packages/web2d/src/components/peer/svg/ElementPeer.ts @@ -1,3 +1,5 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable class-methods-use-this */ /* * Copyright [2021] [wisemapping] * @@ -16,50 +18,48 @@ * limitations under the License. */ import { $assert, $defined } from '@wisemapping/core-js'; +import SizeType from '../../SizeType'; import EventUtils from '../utils/EventUtils'; class ElementPeer { - constructor(svgElement) { - this._native = svgElement; - if (!this._native.addEvent) { - // Hack bug: https://bugzilla.mozilla.org/show_bug.cgi?id=740811 - for (const key in Element) { - if (Object.prototype.hasOwnProperty.call(Element, key)) { - this._native[key] = Element.prototype[key]; - } - } - } + _native: SVGElement; + private _parent: ElementPeer | null; + protected _size: SizeType; + private _changeListeners: {}; + private __handlers: Map; + private _children: ElementPeer[]; + private _stokeStyle: string | null; + constructor(svgElement: SVGElement) { + this._native = svgElement; this._size = { width: 1, height: 1 }; this._changeListeners = {}; // http://support.adobe.com/devsup/devsup.nsf/docs/50493.htm // __handlers stores handlers references so they can be removed afterwards this.__handlers = new Map(); + this._children = []; + this._parent = null; + this._stokeStyle = null; } - setChildren(children) { + setChildren(children: ElementPeer[]): void { this._children = children; } - getChildren() { - let result = this._children; - if (!$defined(result)) { - result = []; - this._children = result; - } - return result; + getChildren(): ElementPeer[] { + return this._children; } - getParent() { + getParent(): ElementPeer | null { return this._parent; } - setParent(parent) { + setParent(parent: ElementPeer | null): void { this._parent = parent; } - append(elementPeer) { + append(elementPeer: ElementPeer): void { // Store parent and child relationship. elementPeer.setParent(this); const children = this.getChildren(); @@ -72,7 +72,7 @@ class ElementPeer { EventUtils.broadcastChangeEvent(this, 'strokeStyle'); } - removeChild(elementPeer) { + removeChild(elementPeer: ElementPeer): void { // Store parent and child relationship. elementPeer.setParent(null); let children = this.getChildren(); @@ -93,52 +93,47 @@ class ElementPeer { * http://www.w3.org/TR/DOM-Level-3-Events/events.html * http://developer.mozilla.org/en/docs/addEvent */ - addEvent(type, listener) { + addEvent(type: string, listener) { // wrap it so it can be ~backward compatible with jQuery.trigger const wrappedListener = (e) => listener(e, e.detail); this.__handlers.set(listener, wrappedListener); this._native.addEventListener(type, wrappedListener); } - trigger(type, event) { + trigger(type: string, event) { // TODO: check this for correctness and for real jQuery.trigger replacement this._native.dispatchEvent(new CustomEvent(type, { detail: event })); } - // eslint-disable-next-line class-methods-use-this - cloneEvents(/* from */) { - throw new Error('cloneEvents not implemented'); - } - - removeEvent(type, listener) { + removeEvent(type: string, listener) { this._native.removeEventListener(type, this.__handlers.get(listener)); this.__handlers.delete(listener); } - setSize(width, height) { - if ($defined(width) && this._size.width !== Number.parseFloat(width, 10)) { - this._size.width = Number.parseFloat(width, 10); - this._native.setAttribute('width', this._size.width.toFixed(2)); + setSize(width: number, height: number): void { + if ($defined(width) && this._size.width !== width) { + this._size.width = width; + this._native.setAttribute('width', width.toFixed(0)); } - if ($defined(height) && this._size.height !== Number.parseFloat(height, 10)) { - this._size.height = Number.parseFloat(height, 10); - this._native.setAttribute('height', this._size.height.toFixed(2)); + if ($defined(height) && this._size.height !== height) { + this._size.height = height; + this._native.setAttribute('height', height.toFixed(0)); } EventUtils.broadcastChangeEvent(this, 'strokeStyle'); } - getSize() { + getSize(): SizeType { return { width: this._size.width, height: this._size.height }; } - setFill(color, opacity) { - if ($defined(color)) { + setFill(color: string | null, opacity?: number | null) { + if (color) { this._native.setAttribute('fill', color); } if ($defined(opacity)) { - this._native.setAttribute('fill-opacity', opacity); + this._native.setAttribute('fill-opacity', String(opacity)); } } @@ -162,20 +157,21 @@ class ElementPeer { }; } - setStroke(width, style, color, opacity) { + setStroke(width: number | null, style?: string | null, color?: string | null, opacity?: number) { if ($defined(width)) { this._native.setAttribute('stroke-width', `${width}px`); } - if ($defined(color)) { + + if (color) { this._native.setAttribute('stroke', color); } - if ($defined(style)) { - this._stokeStyle = style; + if (style) { + this._stokeStyle = style; switch (style) { case 'dash': this._native.setAttribute('stroke-dasharray', '5 5'); - this._native.setAttribute('stroke-linecap', null); + this._native.setAttribute('stroke-linecap', ''); break; case 'dot': this._native.setAttribute('stroke-dasharray', '1 8'); @@ -187,8 +183,8 @@ class ElementPeer { this._native.setAttribute('stroke-linecap', 'round'); break; case 'solid': - this._native.setAttribute('stroke-dasharray', null); - this._native.setAttribute('stroke-linecap', null); + this._native.setAttribute('stroke-dasharray', ''); + this._native.setAttribute('stroke-linecap', ''); break; default: throw new Error(`Unsupported style: ${style}`); @@ -196,21 +192,21 @@ class ElementPeer { } if ($defined(opacity)) { - this._native.setAttribute('stroke-opacity', opacity); + this._native.setAttribute('stroke-opacity', String(opacity)); } } - setVisibility(value, fade) { + setVisibility(value: boolean, fade?: number) { this._native.setAttribute('visibility', value ? 'visible' : 'hidden'); - this._native.style.opacity = value ? 1 : 0; + this._native.style.opacity = String(value ? 1 : 0); if (fade) { this._native.style.transition = `visibility ${fade}ms, opacity ${fade}ms`; } else { - this._native.style.transition = null; + this._native.style.transition = ''; } } - isVisible() { + isVisible(): boolean { const visibility = this._native.getAttribute('visibility'); return !(visibility === 'hidden'); } @@ -245,6 +241,9 @@ class ElementPeer { * Move element to the front */ moveToFront() { + if (!this._native.parentNode) { + throw new Error('node not connected to parent'); + } this._native.parentNode.appendChild(this._native); } @@ -252,10 +251,13 @@ class ElementPeer { * Move element to the back */ moveToBack() { + if (!this._native.parentNode) { + throw new Error('node not connected to parent'); + } this._native.parentNode.insertBefore(this._native, this._native.parentNode.firstChild); } - setCursor(type) { + setCursor(type: string) { this._native.style.cursor = type; } @@ -268,9 +270,8 @@ class ElementPeer { dashdot: [5, 3, 1, 3], }; } + protected static svgNamespace = 'http://www.w3.org/2000/svg'; + protected static linkNamespace = 'http://www.w3.org/1999/xlink'; } -ElementPeer.svgNamespace = 'http://www.w3.org/2000/svg'; -ElementPeer.linkNamespace = 'http://www.w3.org/1999/xlink'; - export default ElementPeer; diff --git a/packages/web2d/src/components/peer/svg/ElipsePeer.js b/packages/web2d/src/components/peer/svg/ElipsePeer.ts similarity index 68% rename from packages/web2d/src/components/peer/svg/ElipsePeer.js rename to packages/web2d/src/components/peer/svg/ElipsePeer.ts index fe62e83d..13a77a08 100644 --- a/packages/web2d/src/components/peer/svg/ElipsePeer.js +++ b/packages/web2d/src/components/peer/svg/ElipsePeer.ts @@ -15,38 +15,31 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { $defined } from '@wisemapping/core-js'; +import PositionType from '../../PositionType'; import ElementPeer from './ElementPeer'; class ElipsePeer extends ElementPeer { + private _position: PositionType; + constructor() { - const svgElement = window.document.createElementNS(ElementPeer.svgNamespace, 'ellipse'); + const svgElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'ellipse'); super(svgElement); + this.attachChangeEventListener('strokeStyle', ElementPeer.prototype.updateStrokeStyle); this._position = { x: 0, y: 0 }; - this._size = { width: 5, height: 5 }; } - setSize(width, height) { + setSize(width: number, height: number) { super.setSize(width, height); - if ($defined(width)) { - this._native.setAttribute('rx', width / 2); - } - - if ($defined(height)) { - this._native.setAttribute('ry', height / 2); - } + this._native.setAttribute('rx', (width / 2).toFixed(0)); + this._native.setAttribute('ry', (height / 2).toFixed(0)); } - setPosition(pcx, pcy) { + setPosition(pcx: number, pcy: number) { this._position = { x: pcx, y: pcy }; - if ($defined(pcx)) { - this._native.setAttribute('cx', pcx); - } - if ($defined(pcy)) { - this._native.setAttribute('cy', pcy); - } + this._native.setAttribute('cx', pcx.toFixed(0)); + this._native.setAttribute('cy', pcy.toFixed(0)); } getPosition() { diff --git a/packages/web2d/src/components/peer/svg/FontPeer.js b/packages/web2d/src/components/peer/svg/FontPeer.ts similarity index 56% rename from packages/web2d/src/components/peer/svg/FontPeer.js rename to packages/web2d/src/components/peer/svg/FontPeer.ts index 5d99da52..ae946fdc 100644 --- a/packages/web2d/src/components/peer/svg/FontPeer.js +++ b/packages/web2d/src/components/peer/svg/FontPeer.ts @@ -15,10 +15,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { $assert, $defined } from '@wisemapping/core-js'; +import { $defined } from '@wisemapping/core-js'; +import SizeType from '../../SizeType'; + +export type FontStyle = { + fontFamily?: string; + style?: string; + weight?: string; + size?: string; + color?: string | null; +}; class FontPeer { - constructor(fontName) { + private _size: number; + private _style: string; + private _weight: string; + private _fontName: string; + + constructor(fontName: string) { this._size = 10; this._style = 'normal'; this._weight = 'normal'; @@ -29,69 +43,48 @@ class FontPeer { if ($defined(args.size)) { this._size = Number.parseInt(args.size, 10); } - if ($defined(args.style)) { + if (args.style) { this._style = args.style; } - if ($defined(args.weight)) { + if (args.weight) { this._weight = args.weight; } } - getHtmlSize(scale) { - let result = 0; - if (this._size === 6) { - result = (this._size * scale.height * 43) / 32; - } - if (this._size === 8) { - result = (this._size * scale.height * 42) / 32; - } else if (this._size === 10) { - result = (this._size * scale.height * 42) / 32; - } else if (this._size === 15) { - result = (this._size * scale.height * 42) / 32; - } - - return result.toFixed(1); + getHtmlSize(scale: SizeType): string { + const result = (this._size * scale.height * 42) / 32; + return result.toFixed(); } - getGraphSize() { + getGraphSize(): string { return ((this._size * 43) / 32).toFixed(1); } - getSize() { - return Number.parseInt(this._size, 10); + getSize(): number { + return this._size; } - getStyle() { + getStyle(): string { return this._style; } - getWeight() { + getWeight(): string { return this._weight; } - setSize(value) { - const size = Number.parseInt(value, 10); - $assert(Number.isFinite(size), `size must be a valid integer: ${value}`); - this._size = size; + setSize(value: number) { + this._size = value; } - setStyle(style) { + setStyle(style: string) { this._style = style; } - setWeight(weight) { + setWeight(weight: string) { this._weight = weight; } - getWidthMargin() { - let result = 0; - if (this._size === 10 || this._size === 6) { - result = 4; - } - return result; - } - - getFontName() { + getFontName(): string { return this._fontName; } } diff --git a/packages/web2d/src/components/peer/svg/GroupPeer.js b/packages/web2d/src/components/peer/svg/GroupPeer.ts similarity index 79% rename from packages/web2d/src/components/peer/svg/GroupPeer.js rename to packages/web2d/src/components/peer/svg/GroupPeer.ts index f2484b7d..8ac8034c 100644 --- a/packages/web2d/src/components/peer/svg/GroupPeer.js +++ b/packages/web2d/src/components/peer/svg/GroupPeer.ts @@ -15,13 +15,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { $defined } from '@wisemapping/core-js'; import ElementPeer from './ElementPeer'; import EventUtils from '../utils/EventUtils'; +import PositionType from '../../PositionType'; +import SizeType from '../../SizeType'; class GroupPeer extends ElementPeer { + private _coordSize: SizeType; + private _position: PositionType; + private _coordOrigin: PositionType; + constructor() { - const svgElement = window.document.createElementNS(ElementPeer.svgNamespace, 'g'); + const svgElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'g'); super(svgElement); this._native.setAttribute('preserveAspectRatio', 'none'); this._coordSize = { @@ -39,7 +44,7 @@ class GroupPeer extends ElementPeer { }; } - setCoordSize(width, height) { + setCoordSize(width: number, height: number): void { const change = this._coordSize.width !== width || this._coordSize.height !== height; this._coordSize.width = width; this._coordSize.height = height; @@ -50,7 +55,7 @@ class GroupPeer extends ElementPeer { EventUtils.broadcastChangeEvent(this, 'strokeStyle'); } - getCoordSize() { + getCoordSize(): SizeType { return { width: this._coordSize.width, height: this._coordSize.height, @@ -92,36 +97,35 @@ class GroupPeer extends ElementPeer { updateTransform() { if (this._coordSize.width > 0) { - const sx = (this._size.width / this._coordSize.width).toFixed(2); - const sy = (this._size.height / this._coordSize.height).toFixed(2); + const sx = this._size.width / this._coordSize.width; + const sy = this._size.height / this._coordSize.height; - const cx = (this._position.x - this._coordOrigin.x * sx).toFixed(2); - const cy = (this._position.y - this._coordOrigin.y * sy).toFixed(2); - this._native.setAttribute('transform', `translate(${cx},${cy}) scale(${sx},${sy})`); + const cx = this._position.x - this._coordOrigin.x * sx; + const cy = this._position.y - this._coordOrigin.y * sy; + this._native.setAttribute( + 'transform', + `translate(${cx.toFixed(2)},${cy.toFixed(2)}) scale(${sx.toFixed(2)},${sy.toFixed(2)})`, + ); } else { this._native.removeAttribute('transform'); } } - setOpacity(value) { - this._native.setAttribute('opacity', value); + setOpacity(value: number) { + this._native.setAttribute('opacity', String(value)); } - setCoordOrigin(x, y) { + setCoordOrigin(x: number, y: number) { const change = x !== this._coordOrigin.x || y !== this._coordOrigin.y; - if ($defined(x)) { - this._coordOrigin.x = x; - } + this._coordOrigin.x = x; + this._coordOrigin.y = y; - if ($defined(y)) { - this._coordOrigin.y = y; - } if (change) { this.updateTransform(); } } - setSize(width, height) { + setSize(width: number, height: number) { const change = width !== this._size.width || height !== this._size.height; super.setSize(width, height); if (change) { @@ -129,21 +133,16 @@ class GroupPeer extends ElementPeer { } } - setPosition(x, y) { + setPosition(x: number, y: number) { const change = x !== this._position.x || y !== this._position.y; - if ($defined(x)) { - this._position.x = Number.parseFloat(x, 10); - } - - if ($defined(y)) { - this._position.y = Number.parseFloat(y, 10); - } + this._position.x = x; + this._position.y = y; if (change) { this.updateTransform(); } } - getPosition() { + getPosition(): PositionType { return { x: this._position.x, y: this._position.y, diff --git a/packages/web2d/src/components/peer/svg/ImagePeer.js b/packages/web2d/src/components/peer/svg/ImagePeer.ts similarity index 74% rename from packages/web2d/src/components/peer/svg/ImagePeer.js rename to packages/web2d/src/components/peer/svg/ImagePeer.ts index f32ed928..5b9f1337 100644 --- a/packages/web2d/src/components/peer/svg/ImagePeer.js +++ b/packages/web2d/src/components/peer/svg/ImagePeer.ts @@ -15,33 +15,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import PositionType from '../../PositionType'; import ElementPeer from './ElementPeer'; class ImagePeer extends ElementPeer { + private _position: PositionType; + private _href: string; + constructor() { - const svgElement = window.document.createElementNS(ElementPeer.svgNamespace, 'image'); + const svgElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'image'); super(svgElement); this._position = { x: 0, y: 0 }; this._href = ''; this._native.setAttribute('preserveAspectRatio', 'none'); } - setPosition(x, y) { + setPosition(x: number, y: number): void { this._position = { x, y }; - this._native.setAttribute('y', y); - this._native.setAttribute('x', x); + this._native.setAttribute('y', String(y)); + this._native.setAttribute('x', String(x)); } - getPosition() { + getPosition(): PositionType { return this._position; } - setHref(url) { + setHref(url: string): void { this._native.setAttributeNS(ElementPeer.linkNamespace, 'href', url); this._href = url; } - getHref() { + getHref(): string { return this._href; } } diff --git a/packages/web2d/src/components/peer/svg/PolyLinePeer.js b/packages/web2d/src/components/peer/svg/PolyLinePeer.ts similarity index 74% rename from packages/web2d/src/components/peer/svg/PolyLinePeer.js rename to packages/web2d/src/components/peer/svg/PolyLinePeer.ts index ecdf2745..067bef72 100644 --- a/packages/web2d/src/components/peer/svg/PolyLinePeer.js +++ b/packages/web2d/src/components/peer/svg/PolyLinePeer.ts @@ -20,46 +20,59 @@ import * as PolyLineUtils from '../utils/PolyLineUtils'; import ElementPeer from './ElementPeer'; class PolyLinePeer extends ElementPeer { + private _breakDistance: number; + private _x1: number; + private _y1: number; + private _x2: number; + private _y2: number; + private _style: string; + constructor() { - const svgElement = window.document.createElementNS(ElementPeer.svgNamespace, 'polyline'); + const svgElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'polyline'); super(svgElement); this.setFill('none'); - this.breakDistance = 10; + this._breakDistance = 10; + this._x1 = 0; + this._x2 = 0; + this._y1 = 0; + this._y2 = 0; + this._style = 'Straight'; } - setFrom(x1, y1) { + setFrom(x1: number, y1: number) { this._x1 = x1; this._y1 = y1; this._updatePath(); } - setTo(x2, y2) { + setTo(x2: number, y2: number) { this._x2 = x2; this._y2 = y2; this._updatePath(); } - setStrokeWidth(width) { - this._native.setAttribute('stroke-width', width); + setStrokeWidth(width: number) { + this._native.setAttribute('stroke-width', String(width)); } - setColor(color) { + setColor(color: string) { this._native.setAttribute('stroke', color); } - setStyle(style) { + setStyle(style: string) { this._style = style; this._updatePath(); } - getStyle() { + getStyle(): string { return this._style; } - _updatePath() { + private _updatePath() { if (this._style === 'Straight') { this._updateStraightPath(); - } if (this._style === 'MiddleStraight') { + } + if (this._style === 'MiddleStraight') { this._updateMiddleStraightPath(); } else if (this._style === 'MiddleCurved') { this._updateMiddleCurvePath(); @@ -68,11 +81,11 @@ class PolyLinePeer extends ElementPeer { } } - _updateStraightPath() { + private _updateStraightPath() { if ($defined(this._x1) && $defined(this._x2) && $defined(this._y1) && $defined(this._y2)) { const path = PolyLineUtils.buildStraightPath.call( this, - this.breakDistance, + this._breakDistance, this._x1, this._y1, this._x2, @@ -82,7 +95,7 @@ class PolyLinePeer extends ElementPeer { } } - _updateMiddleCurvePath() { + private _updateMiddleCurvePath() { const x1 = this._x1; const y1 = this._y1; const x2 = this._x2; @@ -99,13 +112,16 @@ class PolyLinePeer extends ElementPeer { if (y2 < y1) { signy = -1; } - const path = `${x1}, ${y1} ${(middlex - 10 * signx).toFixed(0)}, ${y1} ${(middlex).toFixed(0)}, ${y1 + 10 * signy - } ${middlex}, ${y2 - 10 * signy} ${middlex + 10 * signx}, ${y2} ${x2}, ${y2}`; + const path = `${x1}, ${y1} ${(middlex - 10 * signx).toFixed(0)}, ${y1} ${middlex.toFixed( + 0, + )}, ${y1 + 10 * signy} ${middlex}, ${y2 - 10 * signy} ${ + middlex + 10 * signx + }, ${y2} ${x2}, ${y2}`; this._native.setAttribute('points', path); } } - _updateMiddleStraightPath() { + private _updateMiddleStraightPath() { const x1 = this._x1; const y1 = this._y1; const x2 = this._x2; @@ -118,11 +134,11 @@ class PolyLinePeer extends ElementPeer { } } - _updateCurvePath() { + private _updateCurvePath() { if ($defined(this._x1) && $defined(this._x2) && $defined(this._y1) && $defined(this._y2)) { const path = PolyLineUtils.buildCurvedPath.call( this, - this.breakDistance, + this._breakDistance, this._x1, this._y1, this._x2, diff --git a/packages/web2d/src/components/peer/svg/RectPeer.js b/packages/web2d/src/components/peer/svg/RectPeer.ts similarity index 71% rename from packages/web2d/src/components/peer/svg/RectPeer.js rename to packages/web2d/src/components/peer/svg/RectPeer.ts index 8f59b05c..2bf4e461 100644 --- a/packages/web2d/src/components/peer/svg/RectPeer.js +++ b/packages/web2d/src/components/peer/svg/RectPeer.ts @@ -16,43 +16,45 @@ * limitations under the License. */ import { $defined } from '@wisemapping/core-js'; +import PositionType from '../../PositionType'; import ElementPeer from './ElementPeer'; /** * http://www.w3.org/TR/SVG/shapes.html#RectElement */ class RectPeer extends ElementPeer { - constructor(arc) { - const svgElement = window.document.createElementNS(ElementPeer.svgNamespace, 'rect'); + private _arc: number; + constructor(arc: number) { + const svgElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'rect'); super(svgElement); this._arc = arc; this.attachChangeEventListener('strokeStyle', ElementPeer.prototype.updateStrokeStyle); } - setPosition(x, y) { + setPosition(x: number, y: number) { if ($defined(x)) { - this._native.setAttribute('x', Number.parseFloat(x, 10)); + this._native.setAttribute('x', x.toFixed(0)); } if ($defined(y)) { - this._native.setAttribute('y', Number.parseFloat(y, 10)); + this._native.setAttribute('y', y.toFixed(0)); } } - getPosition() { + getPosition(): PositionType { const x = this._native.getAttribute('x'); const y = this._native.getAttribute('y'); - return { x: Number.parseFloat(x, 10), y: Number.parseFloat(y, 10) }; + return { x: Number.parseInt(x!, 10), y: Number.parseInt(y!, 10) }; } - setSize(width, height) { + setSize(width: number, height: number): void { super.setSize(width, height); const min = width < height ? width : height; if ($defined(this._arc)) { // Transform percentages to SVG format. const arc = (min / 2) * this._arc; - this._native.setAttribute('rx', arc.toFixed(1)); - this._native.setAttribute('ry', arc.toFixed(1)); + this._native.setAttribute('rx', arc.toFixed(0)); + this._native.setAttribute('ry', arc.toFixed(0)); } } } diff --git a/packages/web2d/src/components/peer/svg/StraightPeer.js b/packages/web2d/src/components/peer/svg/StraightPeer.ts similarity index 65% rename from packages/web2d/src/components/peer/svg/StraightPeer.js rename to packages/web2d/src/components/peer/svg/StraightPeer.ts index e68e1509..58aaa863 100644 --- a/packages/web2d/src/components/peer/svg/StraightPeer.js +++ b/packages/web2d/src/components/peer/svg/StraightPeer.ts @@ -16,35 +16,44 @@ * limitations under the License. */ import ElementPeer from './ElementPeer'; -import Point from '../../Point'; class StraightLinePeer extends ElementPeer { + private _x1: number; + private _y1: number; + private _x2: number; + private _y2: number; + constructor() { - const svgElement = window.document.createElementNS(ElementPeer.svgNamespace, 'line'); + const svgElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'line'); super(svgElement); + this.attachChangeEventListener('strokeStyle', ElementPeer.prototype.updateStrokeStyle); + this._x1 = 0; + this._x2 = 0; + this._y1 = 10; + this._y2 = 10; } - setFrom(x1, y1) { + setFrom(x1: number, y1: number) { this._x1 = x1; this._y1 = y1; - this._native.setAttribute('x1', x1); - this._native.setAttribute('y1', y1); + this._native.setAttribute('x1', String(x1)); + this._native.setAttribute('y1', String(y1)); } - setTo(x2, y2) { + setTo(x2: number, y2: number) { this._x2 = x2; this._y2 = y2; - this._native.setAttribute('x2', x2); - this._native.setAttribute('y2', y2); + this._native.setAttribute('x2', String(x2)); + this._native.setAttribute('y2', String(y2)); } getFrom() { - return new Point(this._x1, this._y1); + return { x: this._x1, y: this._y1 }; } getTo() { - return new Point(this._x2, this._y2); + return { x: this._x2, y: this._y2 }; } } diff --git a/packages/web2d/src/components/peer/svg/TextPeer.js b/packages/web2d/src/components/peer/svg/TextPeer.ts similarity index 69% rename from packages/web2d/src/components/peer/svg/TextPeer.js rename to packages/web2d/src/components/peer/svg/TextPeer.ts index eb8fd8f1..5e928237 100644 --- a/packages/web2d/src/components/peer/svg/TextPeer.js +++ b/packages/web2d/src/components/peer/svg/TextPeer.ts @@ -16,23 +16,29 @@ * limitations under the License. */ import { $defined } from '@wisemapping/core-js'; -import FontPeer from './FontPeer'; +import FontPeer, { FontStyle } from './FontPeer'; import ElementPeer from './ElementPeer'; import { getPosition } from '../utils/DomUtils'; +import SizeType from '../../SizeType'; class TextPeer extends ElementPeer { - constructor(fontPeer) { - const svgElement = window.document.createElementNS(ElementPeer.svgNamespace, 'text'); + private _position: { x: number; y: number }; + private _font: FontPeer; + private _textAlign: any; + private _text: string | undefined; + + constructor(fontPeer: FontPeer) { + const svgElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'text'); super(svgElement); this._position = { x: 0, y: 0 }; this._font = fontPeer; } - append(element) { + append(element: ElementPeer) { this._native.appendChild(element._native); } - setTextAlignment(align) { + setTextAlignment(align: string) { this._textAlign = align; } @@ -40,7 +46,7 @@ class TextPeer extends ElementPeer { return $defined(this._textAlign) ? this._textAlign : 'left'; } - setText(text) { + setText(text: string) { // Remove all previous nodes ... while (this._native.firstChild) { this._native.removeChild(this._native.firstChild); @@ -49,30 +55,29 @@ class TextPeer extends ElementPeer { this._text = text; if (text) { const lines = text.split('\n'); - const me = this; lines.forEach((line) => { const tspan = window.document.createElementNS(ElementPeer.svgNamespace, 'tspan'); tspan.setAttribute('dy', '1em'); - tspan.setAttribute('x', me.getPosition().x); + tspan.setAttribute('x', String(this.getPosition().x)); tspan.textContent = line.length === 0 ? ' ' : line; - me._native.appendChild(tspan); + this._native.appendChild(tspan); }); } } - getText() { + getText(): any { return this._text; } - setPosition(x, y) { + setPosition(x: number, y: number) { this._position = { x, y }; - this._native.setAttribute('y', y); - this._native.setAttribute('x', x); + this._native.setAttribute('y', String(y)); + this._native.setAttribute('x', String(x)); // tspan must be positioned manually. Array.from(this._native.querySelectorAll('tspan')).forEach((element) => { - element.setAttribute('x', x); + (element as Element).setAttribute('x', String(x)); }); } @@ -84,7 +89,7 @@ class TextPeer extends ElementPeer { return getPosition(this._native); } - setFont(fontName, size, style, weight) { + setFont(fontName: string, size: number, style: string, weight: string): void { if ($defined(fontName)) { this._font = new FontPeer(fontName); } @@ -108,34 +113,30 @@ class TextPeer extends ElementPeer { this._native.setAttribute('font-weight', this._font.getWeight()); } - setColor(color) { + setColor(color: string) { this._native.setAttribute('fill', color); } - getColor() { + getColor(): string | null { return this._native.getAttribute('fill'); } - setTextSize(size) { + setTextSize(size: number) { this._font.setSize(size); this._updateFontStyle(); } - setContentSize(width, height) { - this._native.xTextSize = `${width.toFixed(1)},${height.toFixed(1)}`; - } - - setStyle(style) { + setStyle(style: string) { this._font.setStyle(style); this._updateFontStyle(); } - setWeight(weight) { + setWeight(weight: string) { this._font.setWeight(weight); this._updateFontStyle(); } - setFontName(fontName) { + setFontName(fontName: string): void { const oldFont = this._font; this._font = new FontPeer(fontName); this._font.setSize(oldFont.getSize()); @@ -144,33 +145,33 @@ class TextPeer extends ElementPeer { this._updateFontStyle(); } - getFontStyle() { - return { + getFontStyle(): FontStyle { + const color = this.getColor(); + const style = { fontFamily: this._font.getFontName(), - size: parseInt(this._font.getSize(), 10), + size: String(this._font.getSize()), style: this._font.getStyle(), weight: this._font.getWeight(), + color: color ? color : undefined, }; + return style; } - setSize(size) { + setFontSize(size: number): void { this._font.setSize(size); this._updateFontStyle(); } - getWidth() { - const computedWidth = this._native.getBBox().width; - let width = parseInt(computedWidth, 10); - width += this._font.getWidthMargin(); - return width; + getShapeWidth(): number { + let result = (this._native as SVGGraphicsElement).getBBox().width; + return result; } - getHeight() { - const computedHeight = this._native.getBBox().height; - return parseInt(computedHeight, 10); + getShapeHeight(): number { + return (this._native as SVGGraphicsElement).getBBox().height; } - getHtmlFontSize(scale) { + getHtmlFontSize(scale: SizeType): string { return this._font.getHtmlSize(scale); } } diff --git a/packages/web2d/src/components/peer/svg/WorkspacePeer.js b/packages/web2d/src/components/peer/svg/WorkspacePeer.ts similarity index 76% rename from packages/web2d/src/components/peer/svg/WorkspacePeer.js rename to packages/web2d/src/components/peer/svg/WorkspacePeer.ts index 923dedb1..ecb91703 100644 --- a/packages/web2d/src/components/peer/svg/WorkspacePeer.js +++ b/packages/web2d/src/components/peer/svg/WorkspacePeer.ts @@ -18,12 +18,16 @@ import { $defined } from '@wisemapping/core-js'; import ElementPeer from './ElementPeer'; import EventUtils from '../utils/EventUtils'; +import SizeType from '../../SizeType'; +import PositionType from '../../PositionType'; class WorkspacePeer extends ElementPeer { - constructor(element) { - const svgElement = window.document.createElementNS(ElementPeer.svgNamespace, 'svg'); + constructor() { + const svgElement: SVGElement = window.document.createElementNS( + 'http://www.w3.org/2000/svg', + 'svg', + ); super(svgElement); - this._element = element; this._native.setAttribute('focusable', 'true'); // this._native.setAttribute('id', 'workspace'); this._native.setAttribute('preserveAspectRatio', 'none'); @@ -49,41 +53,35 @@ class WorkspacePeer extends ElementPeer { * */ - setCoordSize(width, height) { + setCoordSize(width: number, height: number) { const viewBox = this._native.getAttribute('viewBox'); let coords = [0, 0, 0, 0]; if (viewBox != null) { - coords = viewBox.split(/ /); + coords = viewBox.split(/ /).map((e: string) => Number.parseFloat(e)); } - if ($defined(width)) { - coords[2] = width.toFixed(5); - } - - if ($defined(height)) { - coords[3] = height.toFixed(5); - } - - this._native.setAttribute('viewBox', coords.join(' ')); + coords[2] = width; + coords[3] = height; + this._native.setAttribute('viewBox', coords.map((e: number) => e.toFixed(0)).join(' ')); this._native.setAttribute('preserveAspectRatio', 'none'); EventUtils.broadcastChangeEvent(this, 'strokeStyle'); } - getCoordSize() { + getCoordSize(): SizeType { const viewBox = this._native.getAttribute('viewBox'); let coords = [1, 1, 1, 1]; if (viewBox != null) { - coords = viewBox.split(/ /); + coords = viewBox.split(/ /).map((e) => Number.parseInt(e)); } return { width: coords[2], height: coords[3] }; } - setCoordOrigin(x, y) { + setCoordOrigin(x: number, y: number): void { const viewBox = this._native.getAttribute('viewBox'); // ViewBox min-x ,min-y by default initializated with 0 and 0. let coords = [0, 0, 0, 0]; if (viewBox != null) { - coords = viewBox.split(/ /); + coords = viewBox.split(/ /).map((e: string) => Number.parseFloat(e)); } if ($defined(x)) { @@ -94,23 +92,21 @@ class WorkspacePeer extends ElementPeer { coords[1] = y; } - this._native.setAttribute('viewBox', coords.join(' ')); + this._native.setAttribute('viewBox', coords.map((e: number) => e.toFixed(0)).join(' ')); } - append(child) { + append(child: ElementPeer): void { super.append(child); EventUtils.broadcastChangeEvent(child, 'onChangeCoordSize'); } - getCoordOrigin() { + getCoordOrigin(): PositionType { const viewBox = this._native.getAttribute('viewBox'); - let coords = [1, 1, 1, 1]; + let coords = [0, 0, 0, 0]; if (viewBox != null) { - coords = viewBox.split(/ /); + coords = viewBox.split(/ /).map((e) => Number.parseFloat(e)); } - const x = parseFloat(coords[0]); - const y = parseFloat(coords[1]); - return { x, y }; + return { x: coords[0], y: coords[1] }; } // eslint-disable-next-line class-methods-use-this diff --git a/packages/web2d/src/components/peer/utils/EventUtils.js b/packages/web2d/src/components/peer/utils/EventUtils.ts similarity index 80% rename from packages/web2d/src/components/peer/utils/EventUtils.js rename to packages/web2d/src/components/peer/utils/EventUtils.ts index f0dd7a2d..ecbf59f0 100644 --- a/packages/web2d/src/components/peer/utils/EventUtils.js +++ b/packages/web2d/src/components/peer/utils/EventUtils.ts @@ -16,9 +16,10 @@ * limitations under the License. */ import { $defined } from '@wisemapping/core-js'; +import ElementPeer from '../svg/ElementPeer'; -const EventUtils = { - broadcastChangeEvent(elementPeer, type) { +class EventUtils { + static broadcastChangeEvent(elementPeer: ElementPeer, type: string) { const listeners = elementPeer.getChangeEventListeners(type); if ($defined(listeners)) { for (let i = 0; i < listeners.length; i++) { @@ -27,12 +28,10 @@ const EventUtils = { } } - const children = elementPeer.getChildren(); - for (let j = 0; j < children.length; j++) { - const child = children[j]; - EventUtils.broadcastChangeEvent(child, type); - } - }, -}; + elementPeer + .getChildren() + .forEach((child: ElementPeer) => EventUtils.broadcastChangeEvent(child, type)); + } +} export default EventUtils; diff --git a/packages/web2d/src/components/peer/utils/PolyLineUtils.js b/packages/web2d/src/components/peer/utils/PolyLineUtils.ts similarity index 88% rename from packages/web2d/src/components/peer/utils/PolyLineUtils.js rename to packages/web2d/src/components/peer/utils/PolyLineUtils.ts index fd2a0635..972cb883 100644 --- a/packages/web2d/src/components/peer/utils/PolyLineUtils.js +++ b/packages/web2d/src/components/peer/utils/PolyLineUtils.ts @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export const buildCurvedPath = (dist, x1, y1, x2, y2) => { +export const buildCurvedPath = (dist: number, x1: number, y1: number, x2: number, y2: number) => { let signx = 1; let signy = 1; if (x2 < x1) { @@ -40,7 +40,7 @@ export const buildCurvedPath = (dist, x1, y1, x2, y2) => { return path; }; -export const buildStraightPath = (dist, x1, y1, x2, y2) => { +export const buildStraightPath = (dist: number, x1: number, y1: number, x2: number, y2: number) => { const middlex = x1 + (x2 - x1 > 0 ? dist : -dist); return `${x1}, ${y1} ${middlex}, ${y1} ${middlex}, ${y2} ${x2}, ${y2}`; }; diff --git a/packages/web2d/src/components/peer/utils/TransformUtils.ts b/packages/web2d/src/components/peer/utils/TransformUtils.ts new file mode 100644 index 00000000..deba43b4 --- /dev/null +++ b/packages/web2d/src/components/peer/utils/TransformUtils.ts @@ -0,0 +1,53 @@ +/* + * Copyright [2021] [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. + */ + +import SizeType from '../../SizeType'; +import ElementPeer from '../svg/ElementPeer'; +import GroupPeer from '../svg/GroupPeer'; +import TextPeer from '../svg/TextPeer'; +import WorkspacePeer from '../svg/WorkspacePeer'; + +class TransformUtil { + static workoutScale(elementPeer: TextPeer): SizeType { + let width = 1; + let height = 1; + let current: ElementPeer | null = elementPeer.getParent(); + while (current) { + if ( + !(current instanceof GroupPeer) && + !(current instanceof WorkspacePeer) && + !(current instanceof TextPeer) + ) { + throw new Error( + `Not supported element as part of the parent hierarchy.${current instanceof GroupPeer}`, + ); + } + + const container = current as GroupPeer; + const coordSize = container.getCoordSize(); + const size = container.getSize(); + + width *= size.width / coordSize.width; + height *= size.height / coordSize.height; + current = container.getParent(); + } + return { width, height }; + } +} + +export default TransformUtil; diff --git a/packages/web2d/src/index.js b/packages/web2d/src/index.ts similarity index 71% rename from packages/web2d/src/index.js rename to packages/web2d/src/index.ts index 4bce72c3..cbcc8f8d 100644 --- a/packages/web2d/src/index.js +++ b/packages/web2d/src/index.ts @@ -17,7 +17,7 @@ */ import Workspace from './components/Workspace'; -import Elipse from './components/Elipse'; +import Ellipse from './components/Ellipse'; import StraightLine from './components/StraightLine'; import PolyLine from './components/PolyLine'; import CurvedLine from './components/CurvedLine'; @@ -27,5 +27,25 @@ import Rect from './components/Rect'; import Text from './components/Text'; import Point from './components/Point'; import Image from './components/Image'; +import WorkspaceElement from './components/WorkspaceElement'; +import Line from './components/Line'; +import ElementPeer from './components/peer/svg/ElementPeer'; +import type StyleAttributes from './components/StyleAttributes'; -export { Arrow, CurvedLine, Elipse, Group, Image, StraightLine, Point, PolyLine, Rect, Text, Workspace }; +export { + Arrow, + CurvedLine, + WorkspaceElement as ElementClass, + Ellipse as Elipse, + Group, + Image, + StraightLine, + Point, + PolyLine, + Rect, + Text, + Workspace, + Line, + ElementPeer, + StyleAttributes, +}; diff --git a/packages/web2d/storybook/src/stories/CurvedLine.js b/packages/web2d/storybook/src/stories/CurvedLine.js index b94ada48..6b048e02 100644 --- a/packages/web2d/storybook/src/stories/CurvedLine.js +++ b/packages/web2d/storybook/src/stories/CurvedLine.js @@ -1,7 +1,7 @@ /* eslint-disable import/prefer-default-export */ // eslint-disable-next-line import/prefer-default-export import CurvedLine from '../../../src/components/CurvedLine'; -import Elipse from '../../../src/components/Elipse'; +import Ellipse from '../../../src/components/Ellipse'; import Workspace from '../../../src/components/Workspace'; import Point from '../../../src/components/Point'; @@ -61,28 +61,28 @@ export const createCurvedLine = ({ workspace.append(line4); // Add referene point ... - const e1 = new Elipse(); + const e1 = new Ellipse(); e1.setSize(5, 5); e1.setPosition(0, 0); e1.setFill('red'); workspace.append(e1); - const e2 = new Elipse(); + const e2 = new Ellipse(); e2.setPosition(-100, -100); e2.setSize(10, 10); workspace.append(e2); - const e3 = new Elipse(); + const e3 = new Ellipse(); e3.setPosition(100, 100); e3.setSize(10, 10); workspace.append(e3); - const e4 = new Elipse(); + const e4 = new Ellipse(); e4.setPosition(-100, 100); e4.setSize(10, 10); workspace.append(e4); - const e5 = new Elipse(); + const e5 = new Ellipse(); e5.setPosition(100, -100); e5.setSize(10, 10); workspace.append(e5); diff --git a/packages/web2d/storybook/src/stories/Element.js b/packages/web2d/storybook/src/stories/Element.js index 77bb4c69..a175ab25 100644 --- a/packages/web2d/storybook/src/stories/Element.js +++ b/packages/web2d/storybook/src/stories/Element.js @@ -1,7 +1,7 @@ /* eslint-disable import/prefer-default-export */ // eslint-disable-next-line import/prefer-default-export import Rect from '../../../src/components/Rect'; -import Elipse from '../../../src/components/Elipse'; +import Ellipse from '../../../src/components/Ellipse'; import Workspace from '../../../src/components/Workspace'; export const createElement = ({ @@ -34,7 +34,7 @@ export const createElement = ({ rect.addEvent('dblclick', onDblClick); // Add referene point ... - const e1 = new Elipse(); + const e1 = new Ellipse(); e1.setSize(70, 70); e1.setPosition(0, 0); e1.setFill('red', fillOpacity); @@ -79,12 +79,12 @@ export const createEventRegistration = ({ workspace.setSize('150px', '150px'); workspace.setCoordSize(150, 150); - const bigElipse = new Elipse(); + const bigElipse = new Ellipse(); bigElipse.setSize(100, 100); bigElipse.setPosition(75, 75); workspace.append(bigElipse); - const smallElipse = new Elipse(); + const smallElipse = new Ellipse(); smallElipse.setSize(50, 50); smallElipse.setPosition(75, 75); smallElipse.setFill('red'); diff --git a/packages/web2d/storybook/src/stories/Ellipse.js b/packages/web2d/storybook/src/stories/Ellipse.js index a5091606..4da504fc 100644 --- a/packages/web2d/storybook/src/stories/Ellipse.js +++ b/packages/web2d/storybook/src/stories/Ellipse.js @@ -1,6 +1,6 @@ /* eslint-disable import/prefer-default-export */ // eslint-disable-next-line import/prefer-default-export -import Elipse from '../../../src/components/Elipse'; +import Ellipse from '../../../src/components/Ellipse'; import Workspace from '../../../src/components/Workspace'; export const createEllipse = ({ @@ -19,7 +19,7 @@ export const createEllipse = ({ workspace.setCoordSize(300, 300); workspace.setCoordOrigin(-150, -150); - const rect = new Elipse(arc); + const rect = new Ellipse(arc); rect.setFill(backgroundColor); const parsedSize = JSON.parse(size); @@ -32,7 +32,7 @@ export const createEllipse = ({ rect.addEvent('click', onClick); // Add referene point ... - const e1 = new Elipse(); + const e1 = new Ellipse(); e1.setSize(5, 5); e1.setPosition(0, 0); e1.setFill('red'); diff --git a/packages/web2d/storybook/src/stories/Group.stories.js b/packages/web2d/storybook/src/stories/Group.stories.js index 67f81878..5289bc7d 100644 --- a/packages/web2d/storybook/src/stories/Group.stories.js +++ b/packages/web2d/storybook/src/stories/Group.stories.js @@ -1,6 +1,6 @@ import Group from '../../../src/components/Group'; import Workspace from '../../../src/components/Workspace'; -import Elipse from '../../../src/components/Elipse'; +import Ellipse from '../../../src/components/Ellipse'; import StraightLine from '../../../src/components/StraightLine'; // More on default export: https://storybook.js.org/docs/html/writing-stories/introduction#default-export @@ -29,7 +29,7 @@ export const Container = () => { group.setCoordOrigin(0, 0); workspace.append(group); - const elipse = new Elipse(); + const elipse = new Ellipse(); elipse.setSize(200, 200); elipse.setPosition(100, 100); group.append(elipse); @@ -78,12 +78,12 @@ export const EventBubbling = (args) => { const group = new Group(groupAttributes); workspace.append(group); - const elipseLeft = new Elipse(); + const elipseLeft = new Ellipse(); elipseLeft.setSize(200, 200); elipseLeft.setPosition(200, 0); group.append(elipseLeft); - const elipseRight = new Elipse(); + const elipseRight = new Ellipse(); elipseRight.setSize(200, 200); elipseRight.setPosition(0, 0); group.append(elipseRight); @@ -118,7 +118,7 @@ export const Nested = () => { groupOuter.setCoordOrigin(0, 0); workspace.append(groupOuter); - const elipseOuter = new Elipse(); + const elipseOuter = new Ellipse(); elipseOuter.setSize(200, 200); elipseOuter.setPosition(100, 100); elipseOuter.setFill('red'); @@ -143,7 +143,7 @@ export const Nested = () => { groupInner.setCoordOrigin(0, 0); groupOuter.append(groupInner); - const elipse = new Elipse(); + const elipse = new Ellipse(); elipse.setSize(200, 200); elipse.setPosition(100, 100); groupInner.append(elipse); @@ -191,7 +191,7 @@ export const CoordSize = () => { workspace.setCoordSize(150, 150); workspace.setCoordOrigin(-20, -20); - const elipseOuter = new Elipse(); + const elipseOuter = new Ellipse(); elipseOuter.setPosition(50, 50); elipseOuter.setSize(100, 100); workspace.append(elipseOuter); @@ -202,7 +202,7 @@ export const CoordSize = () => { group.setPosition(25, 25); workspace.append(group); - const elipseInner = new Elipse(); + const elipseInner = new Ellipse(); elipseInner.setPosition(50, 50); elipseInner.setSize(100, 100); elipseInner.setFill('red'); @@ -246,7 +246,7 @@ export const CoordOrigin = () => { workspace.setCoordSize(200, 200); workspace.setCoordOrigin(-30, -30); - const elipseOuter = new Elipse(); + const elipseOuter = new Ellipse(); elipseOuter.setPosition(50, 50); elipseOuter.setSize(100, 100); workspace.append(elipseOuter); @@ -258,7 +258,7 @@ export const CoordOrigin = () => { group.setPosition(25, 25); workspace.append(group); - const elipseInner = new Elipse(); + const elipseInner = new Ellipse(); elipseInner.setPosition(50, 50); elipseInner.setSize(50, 50); elipseInner.setFill('red'); diff --git a/packages/web2d/storybook/src/stories/Polyline.js b/packages/web2d/storybook/src/stories/Polyline.js index 56964a66..5ca62f34 100644 --- a/packages/web2d/storybook/src/stories/Polyline.js +++ b/packages/web2d/storybook/src/stories/Polyline.js @@ -1,7 +1,7 @@ /* eslint-disable import/prefer-default-export */ // eslint-disable-next-line import/prefer-default-export import PolyLine from '../../../src/components/PolyLine'; -import Elipse from '../../../src/components/Elipse'; +import Ellipse from '../../../src/components/Ellipse'; import Workspace from '../../../src/components/Workspace'; export const createPolyline = ({ @@ -19,27 +19,27 @@ export const createPolyline = ({ workspace.setCoordOrigin(-200, -200); // Add referene point ... - const e1 = new Elipse(); + const e1 = new Ellipse(); e1.setSize(10, 10); e1.setPosition(0, 0); workspace.append(e1); - const e2 = new Elipse(); + const e2 = new Ellipse(); e2.setPosition(-100, -100); e2.setSize(10, 10); workspace.append(e2); - const e3 = new Elipse(); + const e3 = new Ellipse(); e3.setPosition(100, 100); e3.setSize(10, 10); workspace.append(e3); - const e4 = new Elipse(); + const e4 = new Ellipse(); e4.setPosition(-100, 100); e4.setSize(10, 10); workspace.append(e4); - const e5 = new Elipse(); + const e5 = new Ellipse(); e5.setPosition(100, -100); e5.setSize(10, 10); workspace.append(e5); diff --git a/packages/web2d/storybook/src/stories/Rectangle.js b/packages/web2d/storybook/src/stories/Rectangle.js index 6479a53c..231faeb1 100644 --- a/packages/web2d/storybook/src/stories/Rectangle.js +++ b/packages/web2d/storybook/src/stories/Rectangle.js @@ -1,7 +1,7 @@ /* eslint-disable import/prefer-default-export */ // eslint-disable-next-line import/prefer-default-export import Rect from '../../../src/components/Rect'; -import Elipse from '../../../src/components/Elipse'; +import Ellipse from '../../../src/components/Ellipse'; import Workspace from '../../../src/components/Workspace'; export const createRectangle = ({ @@ -33,7 +33,7 @@ export const createRectangle = ({ rect.addEvent('click', onClick); // Add referene point ... - const e1 = new Elipse(); + const e1 = new Ellipse(); e1.setSize(5, 5); e1.setPosition(0, 0); e1.setFill('red'); diff --git a/packages/web2d/storybook/src/stories/Workspace.stories.js b/packages/web2d/storybook/src/stories/Workspace.stories.js index eebe9c8a..a575c42d 100644 --- a/packages/web2d/storybook/src/stories/Workspace.stories.js +++ b/packages/web2d/storybook/src/stories/Workspace.stories.js @@ -1,5 +1,5 @@ import Workspace from '../../../src/components/Workspace'; -import Elipse from '../../../src/components/Elipse'; +import Ellipse from '../../../src/components/Ellipse'; // More on default export: https://storybook.js.org/docs/html/writing-stories/introduction#default-export export default { @@ -14,7 +14,7 @@ export const Visibility = () => { const overflowWorkspace = new Workspace(); overflowWorkspace.setSize('400px', '400px'); - const elipse1 = new Elipse(); + const elipse1 = new Ellipse(); elipse1.setSize(300, 300); elipse1.setPosition(0, 0); overflowWorkspace.append(elipse1); @@ -47,7 +47,7 @@ export const Position = () => { const workPosition = new Workspace(); workPosition.setSize('400px', '400px'); - const elipse = new Elipse(elipseAttr); + const elipse = new Ellipse(elipseAttr); workPosition.append(elipse); workPosition.addItAsChildTo(div); @@ -69,23 +69,23 @@ export const CoordsSize = (args) => { workspace.setSize('100px', '100px'); workspace.setCoordSize(width, height); - let elipse = new Elipse(); + let elipse = new Ellipse(); elipse.setPosition(50, 50); workspace.append(elipse); - elipse = new Elipse(); + elipse = new Ellipse(); elipse.setPosition(0, 0); workspace.append(elipse); - elipse = new Elipse(); + elipse = new Ellipse(); elipse.setPosition(0, 100); workspace.append(elipse); - elipse = new Elipse(); + elipse = new Ellipse(); elipse.setPosition(100, 0); workspace.append(elipse); - elipse = new Elipse(); + elipse = new Ellipse(); elipse.setPosition(100, 100); workspace.append(elipse); return workspace; @@ -147,27 +147,27 @@ export const CoordsOrigin = (args) => { workspace.setCoordSize(100, 100); workspace.setCoordOrigin(x, y); - let elipse = new Elipse(); + let elipse = new Ellipse(); elipse.setPosition(0, 0); workspace.append(elipse); - elipse = new Elipse(); + elipse = new Ellipse(); elipse.setPosition(0, 100); workspace.append(elipse); - elipse = new Elipse(); + elipse = new Ellipse(); elipse.setPosition(100, 0); workspace.append(elipse); - elipse = new Elipse(); + elipse = new Ellipse(); elipse.setPosition(100, 100); workspace.append(elipse); - elipse = new Elipse(); + elipse = new Ellipse(); elipse.setPosition(50, 50); workspace.append(elipse); - elipse = new Elipse(); + elipse = new Ellipse(); elipse.setPosition(100, 100); workspace.append(elipse); diff --git a/packages/web2d/tsconfig.json b/packages/web2d/tsconfig.json new file mode 100644 index 00000000..e6134b61 --- /dev/null +++ b/packages/web2d/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "outDir": "./dist/", + "sourceMap": true, + "module": "amd", + "moduleResolution": "node", + "target": "es6", + "allowJs": true, + "strict": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "declaration": true, + "strictNullChecks": true, + + "noImplicitAny": false, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": true, + "strictFunctionTypes": true, + + "rootDirs": [ + "src", + ] + }, + "include": [ + "src/**/*", "storybook/src/stories", + ], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/packages/web2d/webpack.common.js b/packages/web2d/webpack.common.js index 3e7019c5..4d45c1a1 100644 --- a/packages/web2d/webpack.common.js +++ b/packages/web2d/webpack.common.js @@ -7,11 +7,7 @@ const common = require('../../webpack.common'); const prodConfig = { output: { path: path.resolve(__dirname, 'dist'), - filename: 'web2d.js', - publicPath: '', - library: { - type: 'umd', - }, + filename: 'index.ts', }, }; diff --git a/packages/webapp/cypress/snapshots/editor.cy.ts/editor-page.snap.png b/packages/webapp/cypress/snapshots/editor.cy.ts/editor-page.snap.png index f63ab378..19657d87 100644 Binary files a/packages/webapp/cypress/snapshots/editor.cy.ts/editor-page.snap.png and b/packages/webapp/cypress/snapshots/editor.cy.ts/editor-page.snap.png differ diff --git a/packages/webapp/package.json b/packages/webapp/package.json index 51faf17e..4c2465fd 100644 --- a/packages/webapp/package.json +++ b/packages/webapp/package.json @@ -3,6 +3,7 @@ "version": "5.0.19", "main": "app.jsx", "scripts": { + "bootstrap": "yalc publish;yalc add @wisemapping/editor", "start": "webpack serve --config webpack.dev.js ", "build": "webpack --config webpack.prod.js", "dev": "webpack --config webpack.dev.js", diff --git a/packages/webapp/webpack.common.js b/packages/webapp/webpack.common.js index b4d5e297..1edc06cc 100644 --- a/packages/webapp/webpack.common.js +++ b/packages/webapp/webpack.common.js @@ -27,7 +27,7 @@ const prodConfig = { splitChunks: { cacheGroups: { vendors: { - test: /node_modules\/.*/, + test: /node_modules\/.!(@wisemapping)/, name: 'vendors', chunks: 'all', }, diff --git a/webpack.common.js b/webpack.common.js index 30357fa7..21e0e10c 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -15,7 +15,12 @@ module.exports = { rules: [ { test: /\.(tsx|ts)?$/, - use: 'ts-loader', + use: { + loader: "ts-loader", + options: { + allowTsInNodeModules: true, + }, + }, exclude: '/node_modules/', }, { diff --git a/yarn.lock b/yarn.lock index 75eb3725..663f45bb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -399,11 +399,11 @@ __metadata: linkType: hard "@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.11, @babel/parser@npm:^7.12.7, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.13, @babel/parser@npm:^7.20.7": - version: 7.20.13 - resolution: "@babel/parser@npm:7.20.13" + version: 7.20.15 + resolution: "@babel/parser@npm:7.20.15" bin: parser: ./bin/babel-parser.js - checksum: 7eb2e3d9d9ad5e24b087c88d137f5701d94f049e28b9dce9f3f5c6d4d9b06a0d7c43b9106f1c02df8a204226200e0517de4bc81a339768a4ebd4c59107ea93a4 + checksum: 1d0f47ca67ff2652f1c0ff1570bed8deccbc4b53509e7cd73476af9cc7ed23480c99f1179bd6d0be01612368b92b39e206d330ad6054009d699934848a89298b languageName: node linkType: hard @@ -938,13 +938,13 @@ __metadata: linkType: hard "@babel/plugin-transform-block-scoping@npm:^7.12.12, @babel/plugin-transform-block-scoping@npm:^7.20.2": - version: 7.20.14 - resolution: "@babel/plugin-transform-block-scoping@npm:7.20.14" + version: 7.20.15 + resolution: "@babel/plugin-transform-block-scoping@npm:7.20.15" dependencies: "@babel/helper-plugin-utils": ^7.20.2 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: acf7bf7314022732e70b0b9c3cdc0fd9d158423d01d09436f020b6f87e7c63292790e1fa34fdcc7388ec453dd5e59f664d4fb3bec5e5694ff28e810baa0c9659 + checksum: 1dddf7be578306837074cb5059f8408af0b1c0bfcf922ed920d4aa65d08fb7c6e6129ca254e9879c4c6d2a6be4937111551f51922e8b0e071ed16eb6564a4dbb languageName: node linkType: hard @@ -3382,14 +3382,14 @@ __metadata: languageName: node linkType: hard -"@mui/base@npm:5.0.0-alpha.115": - version: 5.0.0-alpha.115 - resolution: "@mui/base@npm:5.0.0-alpha.115" +"@mui/base@npm:5.0.0-alpha.116": + version: 5.0.0-alpha.116 + resolution: "@mui/base@npm:5.0.0-alpha.116" dependencies: "@babel/runtime": ^7.20.7 "@emotion/is-prop-valid": ^1.2.0 "@mui/types": ^7.2.3 - "@mui/utils": ^5.11.2 + "@mui/utils": ^5.11.7 "@popperjs/core": ^2.11.6 clsx: ^1.2.1 prop-types: ^15.8.1 @@ -3401,14 +3401,14 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10ac89f3cbcb3d2fdf9fb560c07e3b0b0acb3b6f71e261de8a0513342e03a999d2036b434ff40559bc9e7f7110d3f487c1f77b8371d4dfbf79487dfb17a1a5a8 + checksum: fedc225e716cb3fb0a8030977e3570386f44808a287c671a5cf5b8f77a25fe4c5c0d3f13275f8082eb1c67959b07828d41bf6ce77f7f64eafe662c07bda61b12 languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.11.6": - version: 5.11.6 - resolution: "@mui/core-downloads-tracker@npm:5.11.6" - checksum: e1a5c4c8fe767273d1c33a9d022bfd3263f07e1bf16ff9fecddb0b790a89e618badda8d59046141b9c1cfe5c7732fec202725fc5c545af29511a7f6279b91468 +"@mui/core-downloads-tracker@npm:^5.11.7": + version: 5.11.7 + resolution: "@mui/core-downloads-tracker@npm:5.11.7" + checksum: 8d5f9b0133a986a937f049bf9e877b7be991f1fcc0a1e597bb359f68e13d3a5ba214a299352d85adc6ebcb4a7ea861db070e49306a99e4789853cd6aee6d9aae languageName: node linkType: hard @@ -3429,14 +3429,14 @@ __metadata: linkType: hard "@mui/lab@npm:^5.0.0-alpha.98": - version: 5.0.0-alpha.117 - resolution: "@mui/lab@npm:5.0.0-alpha.117" + version: 5.0.0-alpha.118 + resolution: "@mui/lab@npm:5.0.0-alpha.118" dependencies: "@babel/runtime": ^7.20.7 - "@mui/base": 5.0.0-alpha.115 - "@mui/system": ^5.11.5 + "@mui/base": 5.0.0-alpha.116 + "@mui/system": ^5.11.7 "@mui/types": ^7.2.3 - "@mui/utils": ^5.11.2 + "@mui/utils": ^5.11.7 clsx: ^1.2.1 prop-types: ^15.8.1 react-is: ^18.2.0 @@ -3454,20 +3454,20 @@ __metadata: optional: true "@types/react": optional: true - checksum: 9db5507e19a4d3afc726df3f7403bb46f5d97df1129a12b00360c9cda7cf50f4249eb1195eeeca508045cd8b56b0a84fb4a447fc6a62cc161db903f2e8d26c67 + checksum: 9ac5a7727e3d79e5e43e8b6c10167d1d78652096632af5ab76c2be1547cdefb12a14d672ce4b3dd293bbbb6183ff0272d80b182d7a6d49dbfcef3713d6e9edde languageName: node linkType: hard "@mui/material@npm:^5.10.11": - version: 5.11.6 - resolution: "@mui/material@npm:5.11.6" + version: 5.11.7 + resolution: "@mui/material@npm:5.11.7" dependencies: "@babel/runtime": ^7.20.7 - "@mui/base": 5.0.0-alpha.115 - "@mui/core-downloads-tracker": ^5.11.6 - "@mui/system": ^5.11.5 + "@mui/base": 5.0.0-alpha.116 + "@mui/core-downloads-tracker": ^5.11.7 + "@mui/system": ^5.11.7 "@mui/types": ^7.2.3 - "@mui/utils": ^5.11.2 + "@mui/utils": ^5.11.7 "@types/react-transition-group": ^4.4.5 clsx: ^1.2.1 csstype: ^3.1.1 @@ -3487,16 +3487,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: 75043d52cf85a48e53d1f7a9a374945dd80142104a2780c035d5f2b58bc87cfd0a9d7ffd25ecce6c58beeff65689de443115013c29051e15a66f7a9f46471873 + checksum: 350d329a30df18af96241f3c788856ec55a66a9289abe847f84f645e1c741182efec1cefdc8d02f57b5fd0a143fcea7bb7c106caca1b82402c989c8b837ec54b languageName: node linkType: hard -"@mui/private-theming@npm:^5.11.2": - version: 5.11.2 - resolution: "@mui/private-theming@npm:5.11.2" +"@mui/private-theming@npm:^5.11.7": + version: 5.11.7 + resolution: "@mui/private-theming@npm:5.11.7" dependencies: "@babel/runtime": ^7.20.7 - "@mui/utils": ^5.11.2 + "@mui/utils": ^5.11.7 prop-types: ^15.8.1 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -3504,7 +3504,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 4a36ca48a7a8187d46c3e0d21ec08f7cb732bd4a5bac91c959337c8b0af031beb3a6c5ceac979b685c2e0e66321273d55dd54648f925bfdb946d6513fc6150e6 + checksum: 2ffcec8313a439a015ab0827abc469a701021d1ee68db3a0c06e12f902fa0ad76a8bb2970db12b4144021d4f1a51e1c406176fe2343cde5517b60797b9715265 languageName: node linkType: hard @@ -3529,15 +3529,15 @@ __metadata: languageName: node linkType: hard -"@mui/system@npm:^5.11.5": - version: 5.11.5 - resolution: "@mui/system@npm:5.11.5" +"@mui/system@npm:^5.11.7": + version: 5.11.7 + resolution: "@mui/system@npm:5.11.7" dependencies: "@babel/runtime": ^7.20.7 - "@mui/private-theming": ^5.11.2 + "@mui/private-theming": ^5.11.7 "@mui/styled-engine": ^5.11.0 "@mui/types": ^7.2.3 - "@mui/utils": ^5.11.2 + "@mui/utils": ^5.11.7 clsx: ^1.2.1 csstype: ^3.1.1 prop-types: ^15.8.1 @@ -3553,7 +3553,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 1c896d18f8a8cc4f27d0700046e2dfe3d59d3a81d363ba2ed01341415fce675e5651aafe5c548436fa459dfda2a0c44b6e00fd6917111f388701a64303973532 + checksum: 00dbd8e7c62b97595ba75fb5c508454c7235579524ae7aab0e5e8294adf8d42cefbe5437445db7921baaefe37e7251773643f9a943277e8f2e8945970aae2b47 languageName: node linkType: hard @@ -3569,9 +3569,9 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.11.2": - version: 5.11.2 - resolution: "@mui/utils@npm:5.11.2" +"@mui/utils@npm:^5.11.7": + version: 5.11.7 + resolution: "@mui/utils@npm:5.11.7" dependencies: "@babel/runtime": ^7.20.7 "@types/prop-types": ^15.7.5 @@ -3580,7 +3580,7 @@ __metadata: react-is: ^18.2.0 peerDependencies: react: ^17.0.0 || ^18.0.0 - checksum: 69091d9120681dee29fc20220b7db5dd61334194c139df735d932f072dab00eeae6e440058ffbccebbe93d4a3a998c23b6f4df570cb66cdacd023fce9f0f5912 + checksum: eed3731d692ec29d4b7dfd59de1bc35c9355c5e75d3405fa110deb5a7327763bda41ba6b19165ca080006b2bb6a4d1220c4534464d9ff3acac606fef48c26951 languageName: node linkType: hard @@ -5321,12 +5321,12 @@ __metadata: linkType: hard "@types/eslint@npm:*": - version: 8.4.10 - resolution: "@types/eslint@npm:8.4.10" + version: 8.21.0 + resolution: "@types/eslint@npm:8.21.0" dependencies: "@types/estree": "*" "@types/json-schema": "*" - checksum: 21e009ed9ed9bc8920fdafc6e11ff321c4538b4cc18a56fdd59dc5184ea7bbf363c71638c9bdb59fc1254dddcdd567485136ed68b0ee4750948d4e32cb79c689 + checksum: 48823b13e1ffbc6fe22c96d99f691a17507ef5a498c4aed95e3a9076ec6d44ff48ce8a632928b6f82bea92701ac8967bba0d78a5c9de4dfa3f2e12d26dae7da4 languageName: node linkType: hard @@ -5344,7 +5344,7 @@ __metadata: languageName: node linkType: hard -"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.31": +"@types/express-serve-static-core@npm:*, @types/express-serve-static-core@npm:^4.17.33": version: 4.17.33 resolution: "@types/express-serve-static-core@npm:4.17.33" dependencies: @@ -5356,14 +5356,14 @@ __metadata: linkType: hard "@types/express@npm:*, @types/express@npm:^4.17.13": - version: 4.17.16 - resolution: "@types/express@npm:4.17.16" + version: 4.17.17 + resolution: "@types/express@npm:4.17.17" dependencies: "@types/body-parser": "*" - "@types/express-serve-static-core": ^4.17.31 + "@types/express-serve-static-core": ^4.17.33 "@types/qs": "*" "@types/serve-static": "*" - checksum: 43f3ed2cea6e5e83c7c1098c5152f644e975fd764443717ff9c812a1518416a9e7e9f824ffe852c118888cbfb994ed023cad08331f49b19ced469bb185cdd5cd + checksum: 0196dacc275ac3ce89d7364885cb08e7fb61f53ca101f65886dbf1daf9b7eb05c0943e2e4bbd01b0cc5e50f37e0eea7e4cbe97d0304094411ac73e1b7998f4da languageName: node linkType: hard @@ -5562,16 +5562,16 @@ __metadata: linkType: hard "@types/node@npm:*, @types/node@npm:>= 8": - version: 18.11.18 - resolution: "@types/node@npm:18.11.18" - checksum: 03f17f9480f8d775c8a72da5ea7e9383db5f6d85aa5fefde90dd953a1449bd5e4ffde376f139da4f3744b4c83942166d2a7603969a6f8ea826edfb16e6e3b49d + version: 18.11.19 + resolution: "@types/node@npm:18.11.19" + checksum: d7cd19fcfc59cbdd3f9ba0b4072cb7adc21bd575bd8eb7d7e698975e63564aaa83f03434f32b12331f84f73d0b369d9cbe2371e359d9d7f5c3361f4987f4f7da languageName: node linkType: hard "@types/node@npm:^14.0.10 || ^16.0.0, @types/node@npm:^14.14.20 || ^16.0.0": - version: 16.18.11 - resolution: "@types/node@npm:16.18.11" - checksum: 2a3b1da13063debe6e26f732defb5f03ef4ef732c3e08daba838d8850433bd00e537ce1a97ce9bcfc4b15db5218d701d1265fae94e0d6926906bec157e6b46e0 + version: 16.18.12 + resolution: "@types/node@npm:16.18.12" + checksum: fc3271182414f8593018ef8f00b4718116a92f463f619081bd399d9460e7861e1dd7eebc7cf94c23567e418ff397babed077011711aae8d47171b5a81c5bd71d languageName: node linkType: hard @@ -5879,11 +5879,11 @@ __metadata: linkType: hard "@types/yargs@npm:^17.0.8": - version: 17.0.21 - resolution: "@types/yargs@npm:17.0.21" + version: 17.0.22 + resolution: "@types/yargs@npm:17.0.22" dependencies: "@types/yargs-parser": "*" - checksum: 9c1b84ce1afc82982e5c3360ec795bc6450a8857a6b90906a4cf5826f98be2f82780bad48a49953ec0149295003c1775b5c06698aea2d78fecad227b3b0dda3a + checksum: 0773523fda71bafdc52f13f5970039e535a353665a60ba9261149a5c9c2b908242e6e77fbb7a8c06931ec78ce889d64d09673c68ba23eb5f5742d5385d0d1982 languageName: node linkType: hard @@ -5897,13 +5897,14 @@ __metadata: linkType: hard "@typescript-eslint/eslint-plugin@npm:^5.48.0 ": - version: 5.49.0 - resolution: "@typescript-eslint/eslint-plugin@npm:5.49.0" + version: 5.50.0 + resolution: "@typescript-eslint/eslint-plugin@npm:5.50.0" dependencies: - "@typescript-eslint/scope-manager": 5.49.0 - "@typescript-eslint/type-utils": 5.49.0 - "@typescript-eslint/utils": 5.49.0 + "@typescript-eslint/scope-manager": 5.50.0 + "@typescript-eslint/type-utils": 5.50.0 + "@typescript-eslint/utils": 5.50.0 debug: ^4.3.4 + grapheme-splitter: ^1.0.4 ignore: ^5.2.0 natural-compare-lite: ^1.4.0 regexpp: ^3.2.0 @@ -5915,43 +5916,43 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 15423cd9fde1ac3f8ba34526a07e537464e70463f1af784be5567fdc78e5745352fa0a2c3be0c13d066bc4b9720b5fa438d64647f624d29722eb4f158c039dcc + checksum: 351c4a157a7d717cc3835bdc09324b20d649463738a029c5701e5a38cdb162305ff7d56adff196a0c3245c24ea3167bbdac7f1c30399b8c1d495abbdbc1c53d6 languageName: node linkType: hard "@typescript-eslint/parser@npm:^5.48.0": - version: 5.49.0 - resolution: "@typescript-eslint/parser@npm:5.49.0" + version: 5.50.0 + resolution: "@typescript-eslint/parser@npm:5.50.0" dependencies: - "@typescript-eslint/scope-manager": 5.49.0 - "@typescript-eslint/types": 5.49.0 - "@typescript-eslint/typescript-estree": 5.49.0 + "@typescript-eslint/scope-manager": 5.50.0 + "@typescript-eslint/types": 5.50.0 + "@typescript-eslint/typescript-estree": 5.50.0 debug: ^4.3.4 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 87b3760cfc29b3edd3d28fe0d5e9e5a3833d60398d7779ecc657b9e3bfec624cd464176e26b24b0761fb79cc88daddae19560340f91119c4856b91f9663594dd + checksum: 816a421ce9a5c61a2e92499d6d400aed4211ca5b685e0212844b6659f7acfeba1cca0418b462236c44eea6e8a2574cd51ccb7abc2bf4a8cad5b7a275d71ae9bf languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.49.0": - version: 5.49.0 - resolution: "@typescript-eslint/scope-manager@npm:5.49.0" +"@typescript-eslint/scope-manager@npm:5.50.0": + version: 5.50.0 + resolution: "@typescript-eslint/scope-manager@npm:5.50.0" dependencies: - "@typescript-eslint/types": 5.49.0 - "@typescript-eslint/visitor-keys": 5.49.0 - checksum: 466047e24ff8a4195f14aadde39375f22891bdaced09e58c89f2c32af0aa4a0d87e71a5f006f6ab76858e6f30c4b764b1e0ef7bc26713bb78add30638108c45f + "@typescript-eslint/types": 5.50.0 + "@typescript-eslint/visitor-keys": 5.50.0 + checksum: bd49447a834c82cb130e6900644042c3a84195bf7a63483385e90b6454c65856d6f276c997cad6bf9c36c9d0cb168fdde625ce4c78c3b8bcce42da782270794b languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.49.0": - version: 5.49.0 - resolution: "@typescript-eslint/type-utils@npm:5.49.0" +"@typescript-eslint/type-utils@npm:5.50.0": + version: 5.50.0 + resolution: "@typescript-eslint/type-utils@npm:5.50.0" dependencies: - "@typescript-eslint/typescript-estree": 5.49.0 - "@typescript-eslint/utils": 5.49.0 + "@typescript-eslint/typescript-estree": 5.50.0 + "@typescript-eslint/utils": 5.50.0 debug: ^4.3.4 tsutils: ^3.21.0 peerDependencies: @@ -5959,23 +5960,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 9dcee0a21cfdb3549e2305120535af5ab2c5d0cafdd410827e79d7548f8fc4e7da7cbb77a4338ade8b8b8aaf246fee56b919f1857931bbe2ac5df2fbb5e62ee6 + checksum: d2fc2fd10ef300865fd6a902ae92aef6c45cddc4359445f1e5c6dc9511063b52d2170cc6b525763395d4171c177b3d0fffd77cf9a2ab7e01fcd7109bd1a5a585 languageName: node linkType: hard -"@typescript-eslint/types@npm:5.49.0": - version: 5.49.0 - resolution: "@typescript-eslint/types@npm:5.49.0" - checksum: 41f72a043007fc3f3356b5a38d7bfa54871545b4a309810a062f044cff25122413a9660ce6d83d1221762f60d067351d020b0cb68f7e1279817f53e77ce8f33d +"@typescript-eslint/types@npm:5.50.0": + version: 5.50.0 + resolution: "@typescript-eslint/types@npm:5.50.0" + checksum: 1189c63d35abeec685dd519fd923926b884e63d5e10e4a9fe995aebfde59b8a2e10773090ec3ba32a0ec408746b18f6a454d9bedb0b6c7ce8b6066547144fb4d languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.49.0": - version: 5.49.0 - resolution: "@typescript-eslint/typescript-estree@npm:5.49.0" +"@typescript-eslint/typescript-estree@npm:5.50.0": + version: 5.50.0 + resolution: "@typescript-eslint/typescript-estree@npm:5.50.0" dependencies: - "@typescript-eslint/types": 5.49.0 - "@typescript-eslint/visitor-keys": 5.49.0 + "@typescript-eslint/types": 5.50.0 + "@typescript-eslint/visitor-keys": 5.50.0 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -5984,35 +5985,35 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: f331af9f0ef3ce3157c421b8cc727dec5aa0a60add305aa4c676a02c63ec07799105268af192c5ed193a682b7ed804564d29d49bdbd2019678e495d80e65e29a + checksum: cb1ac8d39647da6d52750c713d9635750ed41245ec82f937a159a71ad3bf490ebabfad3b43eeca07bca39d60df30d3a2f31f8bed0061381731d92a62e284b867 languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.49.0": - version: 5.49.0 - resolution: "@typescript-eslint/utils@npm:5.49.0" +"@typescript-eslint/utils@npm:5.50.0": + version: 5.50.0 + resolution: "@typescript-eslint/utils@npm:5.50.0" dependencies: "@types/json-schema": ^7.0.9 "@types/semver": ^7.3.12 - "@typescript-eslint/scope-manager": 5.49.0 - "@typescript-eslint/types": 5.49.0 - "@typescript-eslint/typescript-estree": 5.49.0 + "@typescript-eslint/scope-manager": 5.50.0 + "@typescript-eslint/types": 5.50.0 + "@typescript-eslint/typescript-estree": 5.50.0 eslint-scope: ^5.1.1 eslint-utils: ^3.0.0 semver: ^7.3.7 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 8218c566637d5104dfb2346216f8cb4c244f31c2a39e261aafe554b8abd48bd630a0d0807a0a8d776af8f9d9914c8776d86abf0a523049f3c5619c498a7e5b1e + checksum: 4471ae8b24449300e009f1cc09ee0d38cce20ae9171e8fbf4ef752ce4eb87104cc0d813d8f7051b619fa05e1e7c12b748dad49832911685297b1bbfef3c01f0b languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.49.0": - version: 5.49.0 - resolution: "@typescript-eslint/visitor-keys@npm:5.49.0" +"@typescript-eslint/visitor-keys@npm:5.50.0": + version: 5.50.0 + resolution: "@typescript-eslint/visitor-keys@npm:5.50.0" dependencies: - "@typescript-eslint/types": 5.49.0 + "@typescript-eslint/types": 5.50.0 eslint-visitor-keys: ^3.3.0 - checksum: 46dc7bc713e8825d1fccba521fdf7c6e2f8829e491c2afd44dbe4105c6432e3c3dfe7e1ecb221401269d639264bb4af77b60a7b65521fcff9ab02cd31d8ef782 + checksum: 55319cb7ee7b78d07d9dc67a388d69fe0b7f11cbc79190e17e7f87a39c9992d08dab3b5872d5a7f01094dda28ad6ac61d3573e59015ef70bf138d4c4f8c45b88 languageName: node linkType: hard @@ -6455,9 +6456,11 @@ __metadata: cypress: ^12.3.0 cypress-image-snapshot: ^4.0.1 emoji-picker-react: ^4.4.3 + jest: ^29.4.1 jquery: 3.6.0 lodash: ^4.17.21 mocha: ^9.1.3 + start-server-and-test: ^1.15.3 xml-formatter: ^2.6.1 languageName: unknown linkType: soft @@ -7299,9 +7302,9 @@ __metadata: linkType: hard "async-each@npm:^1.0.1": - version: 1.0.5 - resolution: "async-each@npm:1.0.5" - checksum: 7bd386248c76eb180983d16e912f1b6f5623428c9910200f6a54e3bcc69b6539a6ccf69a026cdaa40060b8112669cc608814acb8fb009e3fa81d736a5a14ea95 + version: 1.0.6 + resolution: "async-each@npm:1.0.6" + checksum: d237e8c39348d5f1441edbd3893692912afbacaf83a2ccce8978ebeea804529a8838654b12208fbbc08c8b0411a1248948ee9bf9291ebe1921aabd5b613bc5db languageName: node linkType: hard @@ -8351,9 +8354,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001449": - version: 1.0.30001449 - resolution: "caniuse-lite@npm:1.0.30001449" - checksum: f1b395f0a5495c1931c53f58441e0db79b8b0f8ef72bb6d241d13c49b05827630efe6793d540610e0a014d8fdda330dd42f981c82951bd4bdcf635480e1a0102 + version: 1.0.30001450 + resolution: "caniuse-lite@npm:1.0.30001450" + checksum: 511b360bfc907b2e437699364cf96b83507bc45043926450056642332bcd6f65a1e72540c828534ae15e0ac906e3e9af46cb2bb84458dd580bc31478e9dce282 languageName: node linkType: hard @@ -9601,8 +9604,8 @@ __metadata: linkType: hard "cypress@npm:*, cypress@npm:^12.3.0": - version: 12.4.1 - resolution: "cypress@npm:12.4.1" + version: 12.5.1 + resolution: "cypress@npm:12.5.1" dependencies: "@cypress/request": ^2.88.10 "@cypress/xvfb": ^1.2.4 @@ -9648,7 +9651,7 @@ __metadata: yauzl: ^2.10.0 bin: cypress: bin/cypress - checksum: 92693734e2a2e044effae8319315e2bd66a53e4c590caad36199f8b3b92a56189dcc41cbb2636b8a8a88ac20b91dd899897f873af4b26f106c9ea2e3d47caf35 + checksum: acea08c933084bbdffe8e0d8f24ecdc3be52731824f09cf2e720c974a153d808f5af1c665d977e46f171e275c590065aeadf729022d1338a6a424e5ec8b119af languageName: node linkType: hard @@ -10338,9 +10341,9 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.4.284": - version: 1.4.284 - resolution: "electron-to-chromium@npm:1.4.284" - checksum: be496e9dca6509dbdbb54dc32146fc99f8eb716d28a7ee8ccd3eba0066561df36fc51418d8bd7cf5a5891810bf56c0def3418e74248f51ea4a843d423603d10a + version: 1.4.286 + resolution: "electron-to-chromium@npm:1.4.286" + checksum: 6b53e2aea63892cb4af85ea4ee5ed2b6d848713519987efcf4c1177a32e2fe6d04a7f591f5bcd1feab0b3c88890c6eaf65b6feb16c0e0319bf07e31de31930af languageName: node linkType: hard @@ -14863,7 +14866,7 @@ __metadata: languageName: node linkType: hard -"jest@npm:^29.3.1": +"jest@npm:^29.3.1, jest@npm:^29.4.1": version: 29.4.1 resolution: "jest@npm:29.4.1" dependencies: @@ -16775,9 +16778,9 @@ __metadata: linkType: hard "node-releases@npm:^2.0.8": - version: 2.0.8 - resolution: "node-releases@npm:2.0.8" - checksum: b1ab02c0d5d8e081bf9537232777a7a787dc8fef07f70feabe70a344599b220fe16462f746ac30f3eed5a58549445ad69368964d12a1f8b3b764f6caab7ba34a + version: 2.0.9 + resolution: "node-releases@npm:2.0.9" + checksum: 3ae6b1b300dc72c1a628861093d339a01aa017d3ad9017b0478384be29d6f9c93b9e26c91fce79728cecaadc04d0f16834b7ae1a018730e3e54962ec8c6aa86f languageName: node linkType: hard @@ -20581,7 +20584,7 @@ __metadata: languageName: node linkType: hard -"start-server-and-test@npm:^1.14.0, start-server-and-test@npm:^1.15.2": +"start-server-and-test@npm:^1.14.0, start-server-and-test@npm:^1.15.2, start-server-and-test@npm:^1.15.3": version: 1.15.3 resolution: "start-server-and-test@npm:1.15.3" dependencies: @@ -21282,8 +21285,8 @@ __metadata: linkType: hard "terser@npm:^5.10.0, terser@npm:^5.14.1, terser@npm:^5.3.4": - version: 5.16.2 - resolution: "terser@npm:5.16.2" + version: 5.16.3 + resolution: "terser@npm:5.16.3" dependencies: "@jridgewell/source-map": ^0.3.2 acorn: ^8.5.0 @@ -21291,7 +21294,7 @@ __metadata: source-map-support: ~0.5.20 bin: terser: bin/terser - checksum: 58f3ea10ebc931ecd8143a8d9749b4567df891352f1bac992e8ee0e5645327150a16a0d7e0263d947fd648075fea4e42653cbec7ba7a4f2f3e1ff7272889a221 + checksum: d3c2ac1c2723c37b698b25b68d76fd315a1277fddde113983d5783d1f2a01dd7b8ed83ba3f54e5e65f0b59dd971ed7be2fdf8d4be94ec694b2d27832d2e7561f languageName: node linkType: hard @@ -21398,9 +21401,9 @@ __metadata: linkType: hard "tinycolor2@npm:^1.4.1": - version: 1.5.2 - resolution: "tinycolor2@npm:1.5.2" - checksum: 9df1ea9a986b03f1aebb1c1ac17fc561e358493f61b56d73ef2d7207fe7bd74eb71cf745b70487b2b5bb1ce33c9e8af7101088bb0b5fc532eaa1f9d1eda4ef31 + version: 1.6.0 + resolution: "tinycolor2@npm:1.6.0" + checksum: 6df4d07fceeedc0a878d7bac47e2cd47c1ceeb1078340a9eb8a295bc0651e17c750f73d47b3028d829f30b85c15e0572c0fd4142083e4c21a30a597e47f47230 languageName: node linkType: hard