mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-25 23:54:55 +01:00
Fix error rendered a children node
This commit is contained in:
parent
d8fbf4ecc9
commit
df26a52047
@ -10,7 +10,7 @@ import FreemindConstant from './freemind/FreemindConstant';
|
|||||||
import VersionNumber from './freemind/importer/VersionNumber';
|
import VersionNumber from './freemind/importer/VersionNumber';
|
||||||
import ObjectFactory from './freemind/ObjectFactory';
|
import ObjectFactory from './freemind/ObjectFactory';
|
||||||
import FreemindMap from './freemind/Map';
|
import FreemindMap from './freemind/Map';
|
||||||
import FreeminNode, { Choise } from './freemind/Node';
|
import FreeminNode from './freemind/Node';
|
||||||
import Arrowlink from './freemind/Arrowlink';
|
import Arrowlink from './freemind/Arrowlink';
|
||||||
import Richcontent from './freemind/Richcontent';
|
import Richcontent from './freemind/Richcontent';
|
||||||
import Icon from './freemind/Icon';
|
import Icon from './freemind/Icon';
|
||||||
@ -19,7 +19,7 @@ import Font from './freemind/Font';
|
|||||||
|
|
||||||
type PositionNodeType = {x: number, y: number}
|
type PositionNodeType = {x: number, y: number}
|
||||||
|
|
||||||
class FreemindExporter implements Exporter {
|
class FreemindExporter extends Exporter {
|
||||||
private mindmap: Mindmap;
|
private mindmap: Mindmap;
|
||||||
|
|
||||||
private nodeMap: Map<number, FreeminNode> = null;
|
private nodeMap: Map<number, FreeminNode> = null;
|
||||||
@ -31,9 +31,18 @@ class FreemindExporter implements Exporter {
|
|||||||
private static wisweToFreeFontSize: Map<number, number> = new Map<number, number>();
|
private static wisweToFreeFontSize: Map<number, number> = new Map<number, number>();
|
||||||
|
|
||||||
constructor(mindmap: Mindmap) {
|
constructor(mindmap: Mindmap) {
|
||||||
|
super(FreemindConstant.SUPPORTED_FREEMIND_VERSION.getVersion(), 'application/xml');
|
||||||
this.mindmap = mindmap;
|
this.mindmap = mindmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exportAndEncode(): Promise<string> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
|
getContentType(): string {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
this.wisweToFreeFontSize.set(6, 10);
|
this.wisweToFreeFontSize.set(6, 10);
|
||||||
this.wisweToFreeFontSize.set(8, 12);
|
this.wisweToFreeFontSize.set(8, 12);
|
||||||
@ -73,7 +82,7 @@ class FreemindExporter implements Exporter {
|
|||||||
|
|
||||||
if (centralTopic) {
|
if (centralTopic) {
|
||||||
this.nodeMap.set(centralTopic.getId(), main);
|
this.nodeMap.set(centralTopic.getId(), main);
|
||||||
this.setTopicPropertiesToNode(main, centralTopic, true);
|
this.setTopicPropertiesToNode({ freemindNode: main, mindmapTopic: centralTopic, isRoot: true });
|
||||||
this.addNodeFromTopic(centralTopic, main);
|
this.addNodeFromTopic(centralTopic, main);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,9 +100,7 @@ class FreemindExporter implements Exporter {
|
|||||||
|
|
||||||
if (relationship.getStartArrow() && relationship.getStartArrow()) arrowlink.setStartarrow('Default');
|
if (relationship.getStartArrow() && relationship.getStartArrow()) arrowlink.setStartarrow('Default');
|
||||||
|
|
||||||
const cloudEdge: Array<Choise> = srcNode.getArrowlinkOrCloudOrEdge();
|
srcNode.setArrowlinkOrCloudOrEdge(arrowlink);
|
||||||
|
|
||||||
cloudEdge.push(arrowlink);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -103,37 +110,18 @@ class FreemindExporter implements Exporter {
|
|||||||
return Promise.resolve(xmlToString);
|
return Promise.resolve(xmlToString);
|
||||||
}
|
}
|
||||||
|
|
||||||
private addNodeFromTopic(mainTopic: INodeModel, destNode: FreeminNode): void {
|
private setTopicPropertiesToNode({ freemindNode, mindmapTopic, isRoot }: { freemindNode: FreeminNode; mindmapTopic: INodeModel; isRoot: boolean; }): void {
|
||||||
const curretnTopics: Array<INodeModel> = mainTopic.getChildren();
|
|
||||||
|
|
||||||
curretnTopics.forEach((currentTopic: INodeModel) => {
|
|
||||||
const newNode: FreeminNode = this.objectFactory.createNode();
|
|
||||||
this.nodeMap.set(currentTopic.getId(), newNode);
|
|
||||||
|
|
||||||
this.setTopicPropertiesToNode(newNode, currentTopic, false);
|
|
||||||
|
|
||||||
destNode.getArrowlinkOrCloudOrEdge().push(newNode);
|
|
||||||
|
|
||||||
this.addNodeFromTopic(currentTopic, newNode);
|
|
||||||
|
|
||||||
const position: PositionNodeType = currentTopic.getPosition();
|
|
||||||
if (position) {
|
|
||||||
const xPos: number = position.x;
|
|
||||||
newNode.setPosition((xPos < 0 ? 'left' : 'right'));
|
|
||||||
} else newNode.setPosition('left');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private setTopicPropertiesToNode(freemindNode: FreeminNode, mindmapTopic: INodeModel, isRoot: boolean): void {
|
|
||||||
freemindNode.setId(`ID_${mindmapTopic.getId()}`);
|
freemindNode.setId(`ID_${mindmapTopic.getId()}`);
|
||||||
|
|
||||||
const text = mindmapTopic.getText();
|
const text = mindmapTopic.getText();
|
||||||
|
|
||||||
|
if (text) {
|
||||||
if (!text.includes('\n')) {
|
if (!text.includes('\n')) {
|
||||||
freemindNode.setText(text);
|
freemindNode.setText(text);
|
||||||
} else {
|
} else {
|
||||||
const richcontent: Richcontent = this.buildRichcontent(text, 'NODE');
|
const richcontent: Richcontent = this.buildRichcontent(text, 'NODE');
|
||||||
freemindNode.getArrowlinkOrCloudOrEdge().push(richcontent);
|
freemindNode.setArrowlinkOrCloudOrEdge(richcontent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const wiseShape: string = mindmapTopic.getShapeType();
|
const wiseShape: string = mindmapTopic.getShapeType();
|
||||||
@ -141,7 +129,7 @@ class FreemindExporter implements Exporter {
|
|||||||
freemindNode.setBackgorundColor(this.rgbToHex(mindmapTopic.getBackgroundColor()));
|
freemindNode.setBackgorundColor(this.rgbToHex(mindmapTopic.getBackgroundColor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wiseShape && !wiseShape) {
|
if (wiseShape) {
|
||||||
const isRootRoundedRectangle = isRoot && TopicShape.ROUNDED_RECT !== wiseShape;
|
const isRootRoundedRectangle = isRoot && TopicShape.ROUNDED_RECT !== wiseShape;
|
||||||
const notIsRootLine = !isRoot && TopicShape.LINE !== wiseShape;
|
const notIsRootLine = !isRoot && TopicShape.LINE !== wiseShape;
|
||||||
|
|
||||||
@ -159,13 +147,37 @@ class FreemindExporter implements Exporter {
|
|||||||
this.addEdgeNode(freemindNode, mindmapTopic);
|
this.addEdgeNode(freemindNode, mindmapTopic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private addNodeFromTopic(mainTopic: INodeModel, destNode: FreeminNode): void {
|
||||||
|
const curretnTopics: Array<INodeModel> = mainTopic.getChildren();
|
||||||
|
|
||||||
|
curretnTopics.forEach((currentTopic: INodeModel) => {
|
||||||
|
const newNode: FreeminNode = this.objectFactory.createNode();
|
||||||
|
this.nodeMap.set(currentTopic.getId(), newNode);
|
||||||
|
|
||||||
|
this.setTopicPropertiesToNode({ freemindNode: newNode, mindmapTopic: currentTopic, isRoot: false });
|
||||||
|
|
||||||
|
destNode.setArrowlinkOrCloudOrEdge(newNode);
|
||||||
|
|
||||||
|
this.addNodeFromTopic(currentTopic, newNode);
|
||||||
|
|
||||||
|
const position: PositionNodeType = currentTopic.getPosition();
|
||||||
|
if (position) {
|
||||||
|
const xPos: number = position.x;
|
||||||
|
newNode.setPosition((xPos < 0 ? 'left' : 'right'));
|
||||||
|
} else newNode.setPosition('left');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private buildRichcontent(text: string, type: string): Richcontent {
|
private buildRichcontent(text: string, type: string): Richcontent {
|
||||||
const richconent: Richcontent = this.objectFactory.createRichcontent();
|
const richconent: Richcontent = this.objectFactory.createRichcontent();
|
||||||
|
|
||||||
richconent.setType(type);
|
richconent.setType(type);
|
||||||
|
|
||||||
|
const textSplit = text.split('\n');
|
||||||
|
|
||||||
let html = '<html><body>';
|
let html = '<html><body>';
|
||||||
|
|
||||||
text.split('\n').forEach((line: string) => {
|
textSplit.forEach((line: string) => {
|
||||||
html += `<p>${line.trim()}</p>`;
|
html += `<p>${line.trim()}</p>`;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -183,7 +195,7 @@ class FreemindExporter implements Exporter {
|
|||||||
const freemindIcon: Icon = new Icon();
|
const freemindIcon: Icon = new Icon();
|
||||||
|
|
||||||
branches
|
branches
|
||||||
.filter((node: INodeModel) => node.getText !== undefined)
|
.filter((node: INodeModel) => node.getText())
|
||||||
.forEach((node: INodeModel) => {
|
.forEach((node: INodeModel) => {
|
||||||
node.getFeatures().forEach((feature: FeatureModel) => {
|
node.getFeatures().forEach((feature: FeatureModel) => {
|
||||||
const type = feature.getType();
|
const type = feature.getType();
|
||||||
@ -196,13 +208,13 @@ class FreemindExporter implements Exporter {
|
|||||||
if (type === 'note') {
|
if (type === 'note') {
|
||||||
const note = feature as NoteModel;
|
const note = feature as NoteModel;
|
||||||
const richcontent: Richcontent = this.buildRichcontent(note.getText(), 'NOTE');
|
const richcontent: Richcontent = this.buildRichcontent(note.getText(), 'NOTE');
|
||||||
freemindNode.getArrowlinkOrCloudOrEdge().push(richcontent);
|
freemindNode.setArrowlinkOrCloudOrEdge(richcontent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'icon') {
|
if (type === 'icon') {
|
||||||
const icon = feature as IconModel;
|
const icon = feature as IconModel;
|
||||||
freemindIcon.setBuiltin(icon.getIconType());
|
freemindIcon.setBuiltin(icon.getIconType());
|
||||||
freemindNode.getArrowlinkOrCloudOrEdge().push(freemindIcon);
|
freemindNode.setArrowlinkOrCloudOrEdge(freemindIcon);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -212,7 +224,7 @@ class FreemindExporter implements Exporter {
|
|||||||
if (mindmapTopic.getBorderColor()) {
|
if (mindmapTopic.getBorderColor()) {
|
||||||
const edgeNode: Edge = this.objectFactory.createEdge();
|
const edgeNode: Edge = this.objectFactory.createEdge();
|
||||||
edgeNode.setColor(this.rgbToHex(mindmapTopic.getBorderColor()));
|
edgeNode.setColor(this.rgbToHex(mindmapTopic.getBorderColor()));
|
||||||
freemainMap.getArrowlinkOrCloudOrEdge().push(edgeNode);
|
freemainMap.setArrowlinkOrCloudOrEdge(edgeNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +279,7 @@ class FreemindExporter implements Exporter {
|
|||||||
if (font.getSize() === null) {
|
if (font.getSize() === null) {
|
||||||
font.setSize(FreemindExporter.wisweToFreeFontSize.get(8).toString());
|
font.setSize(FreemindExporter.wisweToFreeFontSize.get(8).toString());
|
||||||
}
|
}
|
||||||
freemindNode.getArrowlinkOrCloudOrEdge().push(font);
|
freemindNode.setArrowlinkOrCloudOrEdge(font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import Edge from './Edge';
|
|||||||
import Font from './Font';
|
import Font from './Font';
|
||||||
import Icon from './Icon';
|
import Icon from './Icon';
|
||||||
import Node, { Choise } from './Node';
|
import Node, { Choise } from './Node';
|
||||||
|
import Richcontent from './Richcontent';
|
||||||
|
|
||||||
export default class Map {
|
export default class Map {
|
||||||
protected node: Node;
|
protected node: Node;
|
||||||
@ -38,7 +39,6 @@ export default class Map {
|
|||||||
|
|
||||||
// Create main node
|
// Create main node
|
||||||
const mainNode: Node = this.node;
|
const mainNode: Node = this.node;
|
||||||
mainNode.setCentralNode(true);
|
|
||||||
const mainNodeElem = mainNode.toXml(document);
|
const mainNodeElem = mainNode.toXml(document);
|
||||||
mapElem.appendChild(mainNodeElem);
|
mapElem.appendChild(mainNodeElem);
|
||||||
|
|
||||||
@ -53,14 +53,16 @@ export default class Map {
|
|||||||
|
|
||||||
private nodeToXml(childNode: Choise, parentNode: HTMLElement, document: Document): HTMLElement {
|
private nodeToXml(childNode: Choise, parentNode: HTMLElement, document: Document): HTMLElement {
|
||||||
if (childNode instanceof Node) {
|
if (childNode instanceof Node) {
|
||||||
childNode.setCentralNode(false);
|
|
||||||
const childNodeXml = childNode.toXml(document);
|
const childNodeXml = childNode.toXml(document);
|
||||||
parentNode.appendChild(childNodeXml);
|
parentNode.appendChild(childNodeXml);
|
||||||
|
|
||||||
childNode.getArrowlinkOrCloudOrEdge().forEach((node: Choise) => {
|
const childrens = childNode.getArrowlinkOrCloudOrEdge();
|
||||||
|
if (childrens.length > 0) {
|
||||||
|
childrens.forEach((node: Choise) => {
|
||||||
const nodeXml = this.nodeToXml(node, childNodeXml, document);
|
const nodeXml = this.nodeToXml(node, childNodeXml, document);
|
||||||
childNodeXml.appendChild(nodeXml);
|
childNodeXml.appendChild(nodeXml);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return childNodeXml;
|
return childNodeXml;
|
||||||
}
|
}
|
||||||
@ -100,6 +102,13 @@ export default class Map {
|
|||||||
return childNodeXml;
|
return childNodeXml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (childNode instanceof Richcontent) {
|
||||||
|
const childNodeXml = childNode.toXml(document);
|
||||||
|
parentNode.appendChild(childNodeXml);
|
||||||
|
|
||||||
|
return childNodeXml;
|
||||||
|
}
|
||||||
|
|
||||||
return parentNode;
|
return parentNode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,6 @@ class Node {
|
|||||||
|
|
||||||
protected ENCRYPTED_CONTENT: string;
|
protected ENCRYPTED_CONTENT: string;
|
||||||
|
|
||||||
protected centralNode: boolean;
|
|
||||||
|
|
||||||
getArrowlinkOrCloudOrEdge(): Array<Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | Node> {
|
getArrowlinkOrCloudOrEdge(): Array<Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | Node> {
|
||||||
if (!this.arrowlinkOrCloudOrEdge) {
|
if (!this.arrowlinkOrCloudOrEdge) {
|
||||||
this.arrowlinkOrCloudOrEdge = new Array<Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | this>();
|
this.arrowlinkOrCloudOrEdge = new Array<Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | this>();
|
||||||
@ -114,12 +112,8 @@ class Node {
|
|||||||
return this.ENCRYPTED_CONTENT;
|
return this.ENCRYPTED_CONTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCentralNode(): boolean {
|
setArrowlinkOrCloudOrEdge(value: Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | this): void {
|
||||||
return this.centralNode;
|
this.getArrowlinkOrCloudOrEdge().push(value);
|
||||||
}
|
|
||||||
|
|
||||||
setArrowlinkOrCloudOrEdge(value: Array<Arrowlink | Cloud | Edge | Font | Hook | Icon | Richcontent | this>): void {
|
|
||||||
this.arrowlinkOrCloudOrEdge = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setBackgorundColor(value: string): void {
|
setBackgorundColor(value: string): void {
|
||||||
@ -186,25 +180,16 @@ class Node {
|
|||||||
this.ENCRYPTED_CONTENT = value;
|
this.ENCRYPTED_CONTENT = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
setCentralNode(value: boolean): void {
|
|
||||||
this.centralNode = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
toXml(document: Document): HTMLElement {
|
toXml(document: Document): HTMLElement {
|
||||||
// Set node attributes
|
// Set node attributes
|
||||||
const nodeElem = document.createElement('node');
|
const nodeElem = document.createElement('node');
|
||||||
|
|
||||||
if (this.centralNode) {
|
if (this.ID) nodeElem.setAttribute('ID', this.ID);
|
||||||
nodeElem.setAttribute('ID', this.ID);
|
if (this.POSITION) nodeElem.setAttribute('POSITION', this.POSITION);
|
||||||
nodeElem.setAttribute('TEXT', this.TEXT);
|
if (this.STYLE) nodeElem.setAttribute('STYLE', this.STYLE);
|
||||||
|
if (this.BACKGROUND_COLOR) nodeElem.setAttribute('BACKGROUND_COLOR', this.BACKGROUND_COLOR);
|
||||||
return nodeElem;
|
if (this.COLOR) nodeElem.setAttribute('COLOR', this.COLOR);
|
||||||
}
|
if (this.TEXT) nodeElem.setAttribute('TEXT', this.TEXT);
|
||||||
|
|
||||||
nodeElem.setAttribute('ID', this.ID);
|
|
||||||
nodeElem.setAttribute('POSITION', this.POSITION);
|
|
||||||
nodeElem.setAttribute('STYLE', this.STYLE);
|
|
||||||
nodeElem.setAttribute('TEXT', this.TEXT);
|
|
||||||
|
|
||||||
return nodeElem;
|
return nodeElem;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,11 @@ export default class Richcontent {
|
|||||||
|
|
||||||
richcontentElem.setAttribute('TYPE', this.type);
|
richcontentElem.setAttribute('TYPE', this.type);
|
||||||
|
|
||||||
|
if (this.html) {
|
||||||
|
const htmlElement: HTMLElement = document.createElement(this.html);
|
||||||
|
richcontentElem.appendChild(htmlElement);
|
||||||
|
}
|
||||||
|
|
||||||
return richcontentElem;
|
return richcontentElem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ describe('MD export test execution', () => {
|
|||||||
|
|
||||||
describe('MM export test execution', () => {
|
describe('MM export test execution', () => {
|
||||||
test.each(testNames)('Exporting %p suite', async (testName: string) => {
|
test.each(testNames)('Exporting %p suite', async (testName: string) => {
|
||||||
// Load mindmap DOM...
|
// Load mindmap DOM..
|
||||||
const mindmapPath = path.resolve(__dirname, `./input/${testName}.wxml`);
|
const mindmapPath = path.resolve(__dirname, `./input/${testName}.wxml`);
|
||||||
const mapDocument = parseXMLFile(mindmapPath, 'text/xml');
|
const mapDocument = parseXMLFile(mindmapPath, 'text/xml');
|
||||||
|
|
||||||
|
@ -1,7 +1 @@
|
|||||||
<map version="1.0.1">
|
<map version="1.0.1"><node ID="ID_0" TEXT="i18n"><node ID="ID_1" POSITION="right" TEXT="Este es un é con acento"/><node ID="ID_2" POSITION="left" TEXT="Este es una ñ"/><node ID="ID_3" POSITION="right" TEXT="這是一個樣本 Japanise。"/></node></map>
|
||||||
<node ID="ID_0" TEXT="i18n">
|
|
||||||
<node ID="ID_1" POSITION="right" TEXT="Este es un é con acento"/>
|
|
||||||
<node ID="ID_2" POSITION="left" TEXT="Este es una ñ"/>
|
|
||||||
<node ID="ID_3" POSITION="right" TEXT="這是一個樣本 Japanise。"/>
|
|
||||||
</node>
|
|
||||||
</map>
|
|
Loading…
Reference in New Issue
Block a user