diff --git a/packages/mindplot/src/components/export/freemind/Map.ts b/packages/mindplot/src/components/export/freemind/Map.ts index 9cd69068..fc48f34a 100644 --- a/packages/mindplot/src/components/export/freemind/Map.ts +++ b/packages/mindplot/src/components/export/freemind/Map.ts @@ -69,96 +69,104 @@ export default class Freemap { freemap.setVesion(version); const mainTopicElement = rootElem.firstElementChild; - const mainTopic: Node = this.domToNode(mainTopicElement) as Node; + const mainTopic: Node = new Node().loadFromElement(mainTopicElement); freemap.setNode(mainTopic); - // Add all the topics nodes... const childNodes = Array.from(mainTopicElement.childNodes); - const topicsNodes = childNodes + const childsNodes = childNodes .filter( (child: ChildNode) => child.nodeType === 1 && (child as Element).tagName === 'node', ) .map((c) => c as Element); - topicsNodes.forEach((child) => { - const childNode = this.domToNode(child); - mainTopic.setArrowlinkOrCloudOrEdge(childNode); + childsNodes.forEach((child: Element) => { + const node = this.domToNode(child); + mainTopic.setArrowlinkOrCloudOrEdge(node); }); return freemap; } + private filterNodes(child: ChildNode): Element { + let element: Element; + if (child.nodeType === 1) { + if ( + (child as Element).tagName === 'node' + || (child as Element).tagName === 'richcontent' + || (child as Element).tagName === 'font' + || (child as Element).tagName === 'edge' + || (child as Element).tagName === 'arrowlink' + || (child as Element).tagName === 'clud' + || (child as Element).tagName === 'icon' + ) element = child as Element; + } + + return element; + } + private domToNode(nodeElem: Element): Choise { + let node: Choise; + if (nodeElem.tagName === 'node') { - const node: Node = new Node().loadFromElement(nodeElem); + node = new Node().loadFromElement(nodeElem); if (nodeElem.childNodes.length > 0) { - const childElement = Array.from(nodeElem.childNodes) - .filter( - (child: ChildNode) => child.nodeType === 1 && (child as Element).tagName === 'node', - ) + const childNodes = Array.from(nodeElem.childNodes); + const childsNodes = childNodes + .filter((child: ChildNode) => this.filterNodes(child)) .map((c) => c as Element); - childElement.forEach((child) => { - const childNode = new Node().loadFromElement(child); - node.setArrowlinkOrCloudOrEdge(childNode); + childsNodes.forEach((child) => { + const childNode = this.domToNode(child); + if (node instanceof Node) node.setArrowlinkOrCloudOrEdge(childNode); }); } - - return node; } if (nodeElem.tagName === 'font') { - const font: Font = new Font(); - if (nodeElem.getAttribute('NAME')) font.setName(nodeElem.getAttribute('NAME')); - if (nodeElem.getAttribute('BOLD')) font.setBold(nodeElem.getAttribute('BOLD')); - if (nodeElem.getAttribute('ITALIC')) font.setItalic(nodeElem.getAttribute('ITALIC')); - if (nodeElem.getAttribute('SIZE')) font.setSize(nodeElem.getAttribute('SIZE')); - - return font; + node = new Font(); + if (nodeElem.getAttribute('NAME')) node.setName(nodeElem.getAttribute('NAME')); + if (nodeElem.getAttribute('BOLD')) node.setBold(nodeElem.getAttribute('BOLD')); + if (nodeElem.getAttribute('ITALIC')) node.setItalic(nodeElem.getAttribute('ITALIC')); + if (nodeElem.getAttribute('SIZE')) node.setSize(nodeElem.getAttribute('SIZE')); } if (nodeElem.tagName === 'edge') { - const edge = new Edge(); - if (nodeElem.getAttribute('COLOR')) edge.setColor(nodeElem.getAttribute('COLOR')); - if (nodeElem.getAttribute('STYLE')) edge.setStyle(nodeElem.getAttribute('STYLE')); - if (nodeElem.getAttribute('WIDTH')) edge.setWidth(nodeElem.getAttribute('WIDTH')); - - return edge; + node = new Edge(); + if (nodeElem.getAttribute('COLOR')) node.setColor(nodeElem.getAttribute('COLOR')); + if (nodeElem.getAttribute('STYLE')) node.setStyle(nodeElem.getAttribute('STYLE')); + if (nodeElem.getAttribute('WIDTH')) node.setWidth(nodeElem.getAttribute('WIDTH')); } if (nodeElem.tagName === 'arrowlink') { - const arrowlink = new Arrowlink(); - if (nodeElem.getAttribute('COLOR')) arrowlink.setColor(nodeElem.getAttribute('COLOR')); - if (nodeElem.getAttribute('DESTINATION')) arrowlink.setDestination(nodeElem.getAttribute('DESTINATION')); - if (nodeElem.getAttribute('ENDARROW')) arrowlink.setEndarrow(nodeElem.getAttribute('ENDARROW')); - if (nodeElem.getAttribute('ENDINCLINATION')) arrowlink.setEndinclination(nodeElem.getAttribute('ENDINCLINATION')); - if (nodeElem.getAttribute('ID')) arrowlink.setId(nodeElem.getAttribute('ID')); - if (nodeElem.getAttribute('STARTARROW')) arrowlink.setStartarrow(nodeElem.getAttribute('STARTARROW')); - if (nodeElem.getAttribute('STARTINCLINATION')) arrowlink.setStartinclination(nodeElem.getAttribute('STARTINCLINATION')); - - return arrowlink; + node = new Arrowlink(); + if (nodeElem.getAttribute('COLOR')) node.setColor(nodeElem.getAttribute('COLOR')); + if (nodeElem.getAttribute('DESTINATION')) node.setDestination(nodeElem.getAttribute('DESTINATION')); + if (nodeElem.getAttribute('ENDARROW')) node.setEndarrow(nodeElem.getAttribute('ENDARROW')); + if (nodeElem.getAttribute('ENDINCLINATION')) node.setEndinclination(nodeElem.getAttribute('ENDINCLINATION')); + if (nodeElem.getAttribute('ID')) node.setId(nodeElem.getAttribute('ID')); + if (nodeElem.getAttribute('STARTARROW')) node.setStartarrow(nodeElem.getAttribute('STARTARROW')); + if (nodeElem.getAttribute('STARTINCLINATION')) node.setStartinclination(nodeElem.getAttribute('STARTINCLINATION')); } if (nodeElem.tagName === 'cloud') { - const cloud = new Cloud(); - if (nodeElem.getAttribute('COLOR')) cloud.setColor(nodeElem.getAttribute('COLOR')); + node = new Cloud(); + if (nodeElem.getAttribute('COLOR')) node.setColor(nodeElem.getAttribute('COLOR')); } if (nodeElem.tagName === 'icon') { - const icon = new Icon(); - if (nodeElem.getAttribute('BUILTIN')) icon.setBuiltin(nodeElem.getAttribute('BUILTIN')); + node = new Icon(); + if (nodeElem.getAttribute('BUILTIN')) node.setBuiltin(nodeElem.getAttribute('BUILTIN')); } if (nodeElem.tagName === 'richcontent') { - const richcontent = new Richcontent(); + node = new Richcontent(); - if (nodeElem.getAttribute('TYPE')) richcontent.setType(nodeElem.getAttribute('TYPE')); - if (nodeElem.lastElementChild) richcontent.setHtml(String(nodeElem.lastElementChild)); + if (nodeElem.getAttribute('TYPE')) node.setType(nodeElem.getAttribute('TYPE')); + if (nodeElem.lastElementChild) node.setHtml(String(nodeElem.getElementsByTagName('html')[0].outerHTML.trim())); } - const nodeDefault = new Node(); - return nodeDefault; + return node; } private nodeToXml(childNode: Choise, parentNode: HTMLElement, document: Document): HTMLElement { diff --git a/packages/mindplot/src/components/import/FreemindImporter.ts b/packages/mindplot/src/components/import/FreemindImporter.ts index 3bc90dc6..ece2cd7c 100644 --- a/packages/mindplot/src/components/import/FreemindImporter.ts +++ b/packages/mindplot/src/components/import/FreemindImporter.ts @@ -27,8 +27,6 @@ export default class FreemindImporter extends Importer { private relationship: Array; - private currentId: number; - constructor(map: FreemindMap) { super(); this.freemindMap = map; @@ -38,6 +36,7 @@ export default class FreemindImporter extends Importer { this.mindmap = new Mindmap(nameMap); this.nodesmap = new Map(); this.relationship = new Array(); + let wiseTopicId = 0; const version: string = this.freemindMap.getVersion(); @@ -52,20 +51,21 @@ export default class FreemindImporter extends Importer { const freeNode: FreemindNode = this.freemindMap.getNode(); this.mindmap.setVersion(FreemindConstant.CODE_VERSION); - const wiseTopic = this.mindmap.createNode('CentralTopic', 0); - wiseTopic.setId(this.currentId++); + + wiseTopicId++; + const wiseTopic = this.mindmap.createNode('CentralTopic'); wiseTopic.setPosition(0, 0); + wiseTopic.setId(wiseTopicId); - this.convertNodeProperties(freeNode, wiseTopic); - - wiseTopic.setShapeType(TopicShape.ROUNDED_RECT); + this.convertNodeProperties(freeNode, wiseTopic, true); this.nodesmap.set(freeNode.getId(), wiseTopic); - this.convertChildNodes(freeNode, wiseTopic, this.mindmap, 1); + this.convertChildNodes(freeNode, wiseTopic, this.mindmap, 1, wiseTopicId); this.addRelationship(this.mindmap); this.mindmap.setDescription(description); + this.mindmap.addBranch(wiseTopic); return Promise.resolve(this.mindmap); } @@ -126,21 +126,21 @@ export default class FreemindImporter extends Importer { } } - private convertNodeProperties(freeNode: FreemindNode, wiseTopic: NodeModel): void { + private convertNodeProperties(freeNode: FreemindNode, wiseTopic: NodeModel, centralTopic: boolean): void { const text: string = freeNode.getText(); - wiseTopic.setText(text); + if (text) wiseTopic.setText(text); const bgColor: string = freeNode.getBackgorundColor(); - wiseTopic.setBackgroundColor(bgColor); + if (bgColor) wiseTopic.setBackgroundColor(bgColor); - const shape = this.getShapeFromFreeNode(freeNode); - wiseTopic.setShapeType(shape); + if (centralTopic === false) { + const shape = this.getShapeFromFreeNode(freeNode); + if (shape && shape !== 'fork') wiseTopic.setShapeType(shape); + } // Check for style... const fontStyle = this.generateFontStyle(freeNode, null); - if (fontStyle) { - wiseTopic.setFontStyle(fontStyle); - } + if (fontStyle && fontStyle !== ';;;;') wiseTopic.setFontStyle(fontStyle); // Is there any link... const url: string = freeNode.getLink(); @@ -150,10 +150,10 @@ export default class FreemindImporter extends Importer { } const folded = Boolean(freeNode.getFolded()); - wiseTopic.setChildrenShrunken(folded); + if (folded) wiseTopic.setChildrenShrunken(folded); } - private convertChildNodes(freeParent: FreemindNode, wiseParent: NodeModel, mindmap: Mindmap, depth: number): void { + private convertChildNodes(freeParent: FreemindNode, wiseParent: NodeModel, mindmap: Mindmap, depth: number, nodeId: number): void { const freeChilden = freeParent.getArrowlinkOrCloudOrEdge(); let currentWiseTopic: NodeModel = wiseParent; let order = 0; @@ -162,15 +162,15 @@ export default class FreemindImporter extends Importer { freeChilden.forEach((child) => { if (child instanceof FreemindNode) { - const freeChild: FreemindNode = child as FreemindNode; - const wiseChild = mindmap.createNode('MainTopic', this.currentId++); + const wiseId = parseInt(child.getId().split('_')[1], 10); + const wiseChild = mindmap.createNode('MainTopic', wiseId); - this.nodesmap.set(freeChild.getId(), wiseChild); + this.nodesmap.set(child.getId(), wiseChild); let norder: number; if (depth !== 1) { norder = order++; - } else if (freeChild.getPosition() && freeChild.getPosition() === FreemindConstant.POSITION_LEFT) { + } else if (child.getPosition() && child.getPosition() === FreemindConstant.POSITION_LEFT) { norder = firstLevelLeftOrder; firstLevelLeftOrder += 2; } else { @@ -181,14 +181,16 @@ export default class FreemindImporter extends Importer { wiseChild.setOrder(norder); // Convert node position... - const childrenCountSameSide = this.getChildrenCountSameSide(freeChilden, freeChild); - const position: {x: number, y: number} = this.convertPosition(wiseParent, freeChild, depth, norder, childrenCountSameSide); + const childrenCountSameSide = this.getChildrenCountSameSide(freeChilden, child); + const position: {x: number, y: number} = this.convertPosition(wiseParent, child, depth, norder, childrenCountSameSide); wiseChild.setPosition(position.x, position.y); // Convert the rest of the node properties... - this.convertNodeProperties(freeChild, wiseChild); + this.convertNodeProperties(child, wiseChild, false); - this.convertChildNodes(freeChild, wiseChild, mindmap, depth + 1); + if (child.getArrowlinkOrCloudOrEdge().length > 0) { + this.convertChildNodes(child, wiseChild, mindmap, depth++, nodeId); + } if (wiseChild !== wiseParent) { wiseParent.append(wiseChild); @@ -233,18 +235,12 @@ export default class FreemindImporter extends Importer { } if (child instanceof FreemindRichcontent) { - const content: FreemindRichcontent = child as FreemindRichcontent; - const type: string = content.getType(); - - if (type === FreemindConstant.NODE_TYPE) { - const text = this.html2text(content); - currentWiseTopic.setText(text); - } else { - let text = this.html2text(content); - const mindmapNote: NoteModel = new NoteModel({ text: '' }); - text = text || FreemindConstant.EMPTY_NOTE; - mindmapNote.setText(text); - currentWiseTopic.addFeature(mindmapNote); + const type = child.getType(); + if (type === 'NOTE') { + // Formating text + const text = this.html2Text(child.getHtml()); + const noteModel: NoteModel = new NoteModel({ text: text || FreemindConstant.EMPTY_NOTE }); + currentWiseTopic.addFeature(noteModel); } } @@ -293,9 +289,7 @@ export default class FreemindImporter extends Importer { freeChilden.forEach((child) => { if (child instanceof FreemindNode) { - const node: FreemindNode = child as FreemindNode; - - let side = node.getPosition(); + let side = child.getPosition(); if (!side) { side = FreemindConstant.POSITION_RIGHT; } @@ -315,8 +309,6 @@ export default class FreemindImporter extends Importer { result = TopicShape.ROUNDED_RECT; } else if (node.getBackgorundColor()) { result = TopicShape.RECTANGLE; - } else { - result = TopicShape.LINE; } return result; } @@ -395,12 +387,9 @@ export default class FreemindImporter extends Importer { }; } - private html2text(content: FreemindRichcontent): string { - const parser = new DOMParser(); - const doc = parser.parseFromString(content.getHtml(), 'text/html'); - doc.querySelector('br').append('\\n'); - doc.querySelector('p').append('\\n'); - doc.querySelector('div').append('\\n'); - return doc.textContent.replace('\\\\n', '\\n').trim(); + private html2Text(content: string): string { + const contentConvert = content.replace(/(<([^>]+)>)/gi, ''); + contentConvert.replace('\t', ''); + return contentConvert.trim(); } } diff --git a/packages/mindplot/test/unit/export/expected/complex.wxml b/packages/mindplot/test/unit/export/expected/complex.wxml index 91268870..76b3603a 100644 --- a/packages/mindplot/test/unit/export/expected/complex.wxml +++ b/packages/mindplot/test/unit/export/expected/complex.wxml @@ -1,5 +1,5 @@ { // Load mindmap DOM.. const mindmapPath = path.resolve(__dirname, `./expected/${testName}.wxml`); - const mindmapMapDocument = parseXMLFile(mindmapPath, 'text/xml'); + const mindmapDocument = parseXMLFile(mindmapPath, 'text/xml'); + const serializer = XMLSerializerFactory.createInstanceFromDocument(mindmapDocument); + const mindmapExpect = serializer.loadFromDom(mindmapDocument, testName); - // Convert to mindmap... - const serializer = XMLSerializerFactory.createInstanceFromDocument(mindmapMapDocument); - const mindmapExpect = serializer.loadFromDom(mindmapMapDocument, testName); - - expect(actualMindmap).toEqual(mindmapExpect); + // Compare with expected... + if (actualMindmap !== mindmapExpect) { + const diffResult = diff(actualMindmap, mindmapExpect); + console.log(diffResult); + expect(actualMindmap).toEqual(mindmapExpect); + } };