From bccd26aad6552c91adcddca05e499ff964476d89 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Thu, 24 Nov 2022 01:07:28 -0800 Subject: [PATCH] WIp --- .../src/components/export/freemind/Map.ts | 124 +++++++++++------- .../src/components/export/freemind/Node.ts | 2 +- .../src/components/import/FreemindImporter.ts | 2 +- .../src/components/layout/BalancedSorter.ts | 23 ++-- .../src/components/model/INodeModel.ts | 2 +- .../persistence/XMLSerializerBeta.ts | 7 +- .../persistence/XMLSerializerTango.ts | 27 ++-- .../src/components/widget/ToolbarNotifier.ts | 2 +- .../test/unit/export/expected/emptyNodes.wxml | 2 +- packages/mindplot/tsconfig.json | 2 +- 10 files changed, 108 insertions(+), 85 deletions(-) diff --git a/packages/mindplot/src/components/export/freemind/Map.ts b/packages/mindplot/src/components/export/freemind/Map.ts index 0f7c21d5..672bfe6d 100644 --- a/packages/mindplot/src/components/export/freemind/Map.ts +++ b/packages/mindplot/src/components/export/freemind/Map.ts @@ -73,24 +73,27 @@ export default class Freemap { freemap.setVesion(version); const mainTopicElement = rootElem.firstElementChild; - const mainTopic: Node = new Node().loadFromElement(mainTopicElement); - freemap.setNode(mainTopic); + if (mainTopicElement) { + const mainTopic: Node = new Node().loadFromElement(mainTopicElement); + freemap.setNode(mainTopic); - const childNodes = Array.from(mainTopicElement.childNodes); - const childsNodes = childNodes - .filter((child: ChildNode) => child.nodeType === 1 && (child as Element).tagName === 'node') - .map((c) => c as Element); - - childsNodes.forEach((child: Element) => { - const node = this.domToNode(child); - mainTopic.setArrowlinkOrCloudOrEdge(node); - }); + const childNodes = Array.from(mainTopicElement.childNodes); + const childsNodes = childNodes + .filter((child: ChildNode) => child.nodeType === 1 && (child as Element).tagName === 'node') + .map((c) => c as Element); + childsNodes.forEach((child: Element) => { + const node = this.domToNode(child); + if (node) { + mainTopic.setArrowlinkOrCloudOrEdge(node); + } + }); + } return freemap; } - private filterNodes(child: ChildNode): Element { - let element: Element; + private filterNodes(child: ChildNode): Element | null { + let element: Element | null = null; if (child.nodeType === 1) { if ( (child as Element).tagName === 'node' || @@ -108,8 +111,8 @@ export default class Freemap { return element; } - private domToNode(nodeElem: Element): Choise { - let node: Choise; + private domToNode(nodeElem: Element): Choise | null { + let node: Choise | null = null; if (nodeElem.tagName === 'node') { node = new Node().loadFromElement(nodeElem); @@ -122,84 +125,105 @@ export default class Freemap { childsNodes.forEach((child) => { const childNode = this.domToNode(child); - if (node instanceof Node) node.setArrowlinkOrCloudOrEdge(childNode); + if (node instanceof Node && childNode) { + node.setArrowlinkOrCloudOrEdge(childNode); + } }); } } if (nodeElem.tagName === 'font') { node = new Font(); - if (nodeElem.getAttribute('NAME')) { - node.setName(nodeElem.getAttribute('NAME')); + + const nameAttr = nodeElem.getAttribute('NAME'); + if (nameAttr) { + node.setName(nameAttr); } - if (nodeElem.getAttribute('BOLD')) { - node.setBold(nodeElem.getAttribute('BOLD')); + + const boldAttr = nodeElem.getAttribute('BOLD'); + if (boldAttr) { + node.setBold(boldAttr); } - if (nodeElem.getAttribute('ITALIC')) { - node.setItalic(nodeElem.getAttribute('ITALIC')); + const italicAttr = nodeElem.getAttribute('ITALIC'); + if (italicAttr) { + node.setItalic(italicAttr); } - if (nodeElem.getAttribute('SIZE')) { - node.setSize(nodeElem.getAttribute('SIZE')); + const sizeAttr = nodeElem.getAttribute('SIZE'); + if (sizeAttr) { + node.setSize(sizeAttr); } } if (nodeElem.tagName === 'edge') { node = new Edge(); - if (nodeElem.getAttribute('COLOR')) { - node.setColor(nodeElem.getAttribute('COLOR')); + const colorAttr = nodeElem.getAttribute('COLOR'); + if (colorAttr) { + node.setColor(colorAttr); } - if (nodeElem.getAttribute('STYLE')) { - node.setStyle(nodeElem.getAttribute('STYLE')); + const styleAttr = nodeElem.getAttribute('STYLE'); + if (styleAttr) { + node.setStyle(styleAttr); } - if (nodeElem.getAttribute('WIDTH')) { - node.setWidth(nodeElem.getAttribute('WIDTH')); + const widthAttr = nodeElem.getAttribute('WIDTH'); + if (widthAttr) { + node.setWidth(widthAttr); } } if (nodeElem.tagName === 'arrowlink') { node = new Arrowlink(); - if (nodeElem.getAttribute('COLOR')) { - node.setColor(nodeElem.getAttribute('COLOR')); + const colorAttr = nodeElem.getAttribute('COLOR'); + if (colorAttr) { + node.setColor(colorAttr); } - if (nodeElem.getAttribute('DESTINATION')) { - node.setDestination(nodeElem.getAttribute('DESTINATION')); + const destAttr = nodeElem.getAttribute('DESTINATION'); + if (destAttr) { + node.setDestination(destAttr); } - if (nodeElem.getAttribute('ENDARROW')) { - node.setEndarrow(nodeElem.getAttribute('ENDARROW')); + const endAttr = nodeElem.getAttribute('ENDARROW'); + if (endAttr) { + node.setEndarrow(endAttr); } - if (nodeElem.getAttribute('ENDINCLINATION')) { - node.setEndinclination(nodeElem.getAttribute('ENDINCLINATION')); + const endIncAttr = nodeElem.getAttribute('ENDINCLINATION'); + if (endIncAttr) { + node.setEndinclination(endIncAttr); } - if (nodeElem.getAttribute('ID')) { - node.setId(nodeElem.getAttribute('ID')); + const idAttr = nodeElem.getAttribute('ID'); + if (idAttr) { + node.setId(idAttr); } - if (nodeElem.getAttribute('STARTARROW')) { - node.setStartarrow(nodeElem.getAttribute('STARTARROW')); + const starAttr = nodeElem.getAttribute('STARTARROW'); + if (starAttr) { + node.setStartarrow(starAttr); } - if (nodeElem.getAttribute('STARTINCLINATION')) { - node.setStartinclination(nodeElem.getAttribute('STARTINCLINATION')); + const startIncAttr = nodeElem.getAttribute('STARTINCLINATION'); + if (startIncAttr) { + node.setStartinclination(startIncAttr); } } if (nodeElem.tagName === 'cloud') { node = new Cloud(); - if (nodeElem.getAttribute('COLOR')) { - node.setColor(nodeElem.getAttribute('COLOR')); + const colorAttr = nodeElem.getAttribute('COLOR'); + if (colorAttr) { + node.setColor(colorAttr); } } if (nodeElem.tagName === 'icon') { node = new Icon(); - if (nodeElem.getAttribute('BUILTIN')) { - node.setBuiltin(nodeElem.getAttribute('BUILTIN')); + const bultInAttr = nodeElem.getAttribute('BUILTIN'); + if (bultInAttr) { + node.setBuiltin(bultInAttr); } } if (nodeElem.tagName === 'richcontent') { node = new Richcontent(); - if (nodeElem.getAttribute('TYPE')) { - node.setType(nodeElem.getAttribute('TYPE')); + const typeAttr = nodeElem.getAttribute('TYPE'); + if (typeAttr) { + node.setType(typeAttr); } if (nodeElem.firstChild && nodeElem.getElementsByTagName('html')) { const content = nodeElem.getElementsByTagName('html'); diff --git a/packages/mindplot/src/components/export/freemind/Node.ts b/packages/mindplot/src/components/export/freemind/Node.ts index bc889e1d..16d56a33 100644 --- a/packages/mindplot/src/components/export/freemind/Node.ts +++ b/packages/mindplot/src/components/export/freemind/Node.ts @@ -69,7 +69,7 @@ class Node { return this.FOLDED; } - getId(): string { + getId(): string | null { return this.ID; } diff --git a/packages/mindplot/src/components/import/FreemindImporter.ts b/packages/mindplot/src/components/import/FreemindImporter.ts index 1bb6e209..50aa621a 100644 --- a/packages/mindplot/src/components/import/FreemindImporter.ts +++ b/packages/mindplot/src/components/import/FreemindImporter.ts @@ -342,7 +342,7 @@ export default class FreemindImporter extends Importer { const id = node.getId(); let idFreeToIdWise: number; - if (id) { + if (id !== null && id !== undefined) { if (id === '_') { this.idDefault++; idFreeToIdWise = this.idDefault; diff --git a/packages/mindplot/src/components/layout/BalancedSorter.ts b/packages/mindplot/src/components/layout/BalancedSorter.ts index 2e67db7b..a3af023d 100644 --- a/packages/mindplot/src/components/layout/BalancedSorter.ts +++ b/packages/mindplot/src/components/layout/BalancedSorter.ts @@ -28,7 +28,7 @@ class BalancedSorter extends AbstractBasicSorter { private static INTERNODE_HORIZONTAL_PADDING = 30; - predict(graph, parent, node: Node, position: PositionType) { + predict(graph, parent, node: Node, position: PositionType): [number, PositionType] { const rootNode = graph.getRootNode(parent); // If it is a dragged node... @@ -44,19 +44,16 @@ class BalancedSorter extends AbstractBasicSorter { } } - let right; - let left; + // Find the order ... + let order: number; if (!position) { - right = this._getChildrenForOrder(parent, graph, 0); - left = this._getChildrenForOrder(parent, graph, 1); - } - // Filter nodes on one side.. - let order; - if (position) { - order = position.x > rootNode.getPosition().x ? 0 : 1; - } else { + const right = this._getChildrenForOrder(parent, graph, 0); + const left = this._getChildrenForOrder(parent, graph, 1); order = right.length - left.length > 0 ? 1 : 0; + } else { + order = position.x > rootNode.getPosition().x ? 0 : 1; } + const direction = order % 2 === 0 ? 1 : -1; // Exclude the dragged node (if set) @@ -79,7 +76,7 @@ class BalancedSorter extends AbstractBasicSorter { } // Try to fit within ... - let result = null; + let result: [number, PositionType] | null = null; const last = children[children.length - 1]; const newestPosition = position || { x: last.getPosition().x, y: last.getPosition().y + 1 }; children.forEach((child, index) => { @@ -234,7 +231,7 @@ class BalancedSorter extends AbstractBasicSorter { return 'Balanced Sorter'; } - protected _getChildrenForOrder(parent: Node, graph: RootedTreeSet, order: number) { + protected _getChildrenForOrder(parent: Node, graph: RootedTreeSet, order: number): Node[] { return this._getSortedChildren(graph, parent).filter( (child) => child.getOrder() % 2 === order % 2, ); diff --git a/packages/mindplot/src/components/model/INodeModel.ts b/packages/mindplot/src/components/model/INodeModel.ts index 4b5e3fac..61b470c6 100644 --- a/packages/mindplot/src/components/model/INodeModel.ts +++ b/packages/mindplot/src/components/model/INodeModel.ts @@ -288,7 +288,7 @@ abstract class INodeModel { abstract getPropertiesKeys(): string[]; - abstract getProperty(key: string): number | string | boolean | undefined; + abstract getProperty(key: string): number | string | boolean; abstract putProperty(key: string, value: number | string | boolean): void; diff --git a/packages/mindplot/src/components/persistence/XMLSerializerBeta.ts b/packages/mindplot/src/components/persistence/XMLSerializerBeta.ts index 3b9e8744..ffc1bc37 100644 --- a/packages/mindplot/src/components/persistence/XMLSerializerBeta.ts +++ b/packages/mindplot/src/components/persistence/XMLSerializerBeta.ts @@ -20,6 +20,7 @@ import Mindmap from '../model/Mindmap'; import FeatureModelFactory from '../model/FeatureModelFactory'; import NodeModel from '../model/NodeModel'; import XMLMindmapSerializer from './XMLMindmapSerializer'; +import FeatureModel from '../model/FeatureModel'; class XMLSerializerBeta implements XMLMindmapSerializer { private static MAP_ROOT_NODE = 'map'; @@ -65,7 +66,7 @@ class XMLSerializerBeta implements XMLMindmapSerializer { } const text = topic.getText(); - if ($defined(text)) { + if (text) { parentTopic.setAttribute('text', text); } @@ -297,9 +298,9 @@ class XMLSerializerBeta implements XMLMindmapSerializer { return topic; } - _deserializeIcon(domElem: Element) { + private _deserializeIcon(domElem: Element): FeatureModel { let icon = domElem.getAttribute('id'); - icon = icon.replace('images/', 'icons/legacy/'); + icon = icon ? icon.replace('images/', 'icons/legacy/') : 'missing'; return FeatureModelFactory.createModel('icon', { id: icon }); } diff --git a/packages/mindplot/src/components/persistence/XMLSerializerTango.ts b/packages/mindplot/src/components/persistence/XMLSerializerTango.ts index abfa8b30..0d387fdb 100644 --- a/packages/mindplot/src/components/persistence/XMLSerializerTango.ts +++ b/packages/mindplot/src/components/persistence/XMLSerializerTango.ts @@ -268,7 +268,7 @@ class XMLSerializerTango implements XMLMindmapSerializer { }); // Clean up from the recursion ... - this._idsMap = null; + this._idsMap = {}; mindmap.setId(mapId); return mindmap; } @@ -389,7 +389,9 @@ class XMLSerializerTango implements XMLMindmapSerializer { for (let j = 0; j < namedNodeMap.length; j++) { const attribute = namedNodeMap.item(j); - attributes[attribute.name] = attribute.value; + if (attribute !== null) { + attributes[attribute.name] = attribute.value; + } } // Has text node ?. @@ -437,7 +439,7 @@ class XMLSerializerTango implements XMLMindmapSerializer { static _deserializeTextAttr(domElem: Element): string { let value = domElem.getAttribute('text'); - if (!$defined(value)) { + if (!value) { const children = domElem.childNodes; for (let i = 0; i < children.length; i++) { const child = children[i]; @@ -448,11 +450,10 @@ class XMLSerializerTango implements XMLMindmapSerializer { } else { // Notes must be decoded ... value = unescape(value); - - // Hack for empty nodes ... - if (value === '') { - value = ' '; - } + } + // Hack for empty nodes ... + if (!value) { + value = ' '; } return value; @@ -462,7 +463,7 @@ class XMLSerializerTango implements XMLMindmapSerializer { return emojiToIconMap[icon]; } - private static _deserializeNodeText(domElem: ChildNode): string | null { + private static _deserializeNodeText(domElem: ChildNode): string { const children = domElem.childNodes; let value: string | null = null; for (let i = 0; i < children.length; i++) { @@ -471,13 +472,13 @@ class XMLSerializerTango implements XMLMindmapSerializer { value = child.nodeValue; } } - return value; + return value !== null ? value : ''; } static _deserializeRelationship(domElement: Element, mindmap: Mindmap): RelationshipModel { - const srcId = Number.parseInt(domElement.getAttribute('srcTopicId'), 10); - const destId = Number.parseInt(domElement.getAttribute('destTopicId'), 10); - const lineType = Number.parseInt(domElement.getAttribute('lineType'), 10); + const srcId = Number.parseInt(domElement.getAttribute('srcTopicId')!, 10); + const destId = Number.parseInt(domElement.getAttribute('destTopicId')!, 10); + const lineType = Number.parseInt(domElement.getAttribute('lineType')!, 10); const srcCtrlPoint = domElement.getAttribute('srcCtrlPoint'); const destCtrlPoint = domElement.getAttribute('destCtrlPoint'); diff --git a/packages/mindplot/src/components/widget/ToolbarNotifier.ts b/packages/mindplot/src/components/widget/ToolbarNotifier.ts index 0f063ece..ea7e97ce 100644 --- a/packages/mindplot/src/components/widget/ToolbarNotifier.ts +++ b/packages/mindplot/src/components/widget/ToolbarNotifier.ts @@ -36,7 +36,7 @@ class ToolbarNotifier { this.container.data('transitioning', true); this.container.text(msg); this.container.css({ - left: ($(window).width() - this.container.width()) / 2 - 9, + left: ($(window).width()! - this.container.width()!) / 2 - 9, }); if (fade) { diff --git a/packages/mindplot/test/unit/export/expected/emptyNodes.wxml b/packages/mindplot/test/unit/export/expected/emptyNodes.wxml index 923cb2e4..741720d0 100644 --- a/packages/mindplot/test/unit/export/expected/emptyNodes.wxml +++ b/packages/mindplot/test/unit/export/expected/emptyNodes.wxml @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/packages/mindplot/tsconfig.json b/packages/mindplot/tsconfig.json index ed87437f..b2a5de29 100644 --- a/packages/mindplot/tsconfig.json +++ b/packages/mindplot/tsconfig.json @@ -10,7 +10,7 @@ "esModuleInterop": true, "resolveJsonModule": true, "declaration": true, - "strictNullChecks": true, + "strictNullChecks": false, "rootDirs": [ "src", ]