2022-03-27 00:07:45 +00:00

238 lines
7.3 KiB
TypeScript

import { createDocument, $assert } from '@wisemapping/core-js';
import Arrowlink from './Arrowlink';
import Cloud from './Cloud';
import Edge from './Edge';
import Font from './Font';
import Icon from './Icon';
import Node, { Choise } from './Node';
import Richcontent from './Richcontent';
export default class Freemap {
protected node: Node;
protected version: string;
getNode(): Node {
return this.node;
}
getVersion(): string {
return this.version;
}
setNode(value: Node) {
this.node = value;
}
setVesion(value: string) {
this.version = value;
}
toXml(): Document {
const document = createDocument();
// Set map attributes
const mapElem = document.createElement('map');
mapElem.setAttribute('version', this.version);
document.appendChild(mapElem);
// Create main node
const mainNode: Node = this.node;
mainNode.setCentralTopic(true);
const mainNodeElem = mainNode.toXml(document);
mapElem.appendChild(mainNodeElem);
const childNodes: Array<Choise> = mainNode.getArrowlinkOrCloudOrEdge();
childNodes.forEach((childNode: Choise) => {
const node = this.nodeToXml(childNode, mainNodeElem, document);
mainNodeElem.appendChild(node);
});
return document;
}
loadFromDom(dom: Document): Freemap {
$assert(dom, 'dom can not be null');
const rootElem = dom.documentElement;
// Is a freemap?
$assert(
rootElem.tagName === 'map',
`This seem not to be a map document. Found tag: ${rootElem.tagName}`,
);
// Start the loading process...
const version = rootElem.getAttribute('version') || '1.0.1';
const freemap: Freemap = new Freemap();
freemap.setVesion(version);
const mainTopicElement = rootElem.firstElementChild;
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);
});
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') {
node = new Node().loadFromElement(nodeElem);
if (nodeElem.childNodes.length > 0) {
const childNodes = Array.from(nodeElem.childNodes);
const childsNodes = childNodes
.filter((child: ChildNode) => this.filterNodes(child))
.map((c) => c as Element);
childsNodes.forEach((child) => {
const childNode = this.domToNode(child);
if (node instanceof Node) node.setArrowlinkOrCloudOrEdge(childNode);
});
}
}
if (nodeElem.tagName === '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') {
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') {
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') {
node = new Cloud();
if (nodeElem.getAttribute('COLOR')) node.setColor(nodeElem.getAttribute('COLOR'));
}
if (nodeElem.tagName === 'icon') {
node = new Icon();
if (nodeElem.getAttribute('BUILTIN')) node.setBuiltin(nodeElem.getAttribute('BUILTIN'));
}
if (nodeElem.tagName === 'richcontent') {
node = new Richcontent();
if (nodeElem.getAttribute('TYPE')) node.setType(nodeElem.getAttribute('TYPE'));
if (nodeElem.firstChild && nodeElem.getElementsByTagName('html')) {
const content = nodeElem.getElementsByTagName('html');
const html = content[0] ? content[0].outerHTML : '';
node.setHtml(html);
}
}
return node;
}
private nodeToXml(childNode: Choise, parentNode: HTMLElement, document: Document): HTMLElement {
if (childNode instanceof Node) {
childNode.setCentralTopic(false);
const childNodeXml = childNode.toXml(document);
parentNode.appendChild(childNodeXml);
const childrens = childNode.getArrowlinkOrCloudOrEdge();
if (childrens.length > 0) {
childrens.forEach((node: Choise) => {
const nodeXml = this.nodeToXml(node, childNodeXml, document);
childNodeXml.appendChild(nodeXml);
});
}
return childNodeXml;
}
if (childNode instanceof Font) {
const childNodeXml = childNode.toXml(document);
parentNode.appendChild(childNodeXml);
return childNodeXml;
}
if (childNode instanceof Edge) {
const childNodeXml = childNode.toXml(document);
parentNode.appendChild(childNodeXml);
return childNodeXml;
}
if (childNode instanceof Arrowlink) {
const childNodeXml = childNode.toXml(document);
parentNode.appendChild(childNodeXml);
return childNodeXml;
}
if (childNode instanceof Cloud) {
const childNodeXml = childNode.toXml(document);
parentNode.appendChild(childNodeXml);
return childNodeXml;
}
if (childNode instanceof Icon) {
const childNodeXml = childNode.toXml(document);
parentNode.appendChild(childNodeXml);
return childNodeXml;
}
if (childNode instanceof Richcontent) {
const childNodeXml = childNode.toXml(document);
parentNode.appendChild(childNodeXml);
return childNodeXml;
}
return parentNode;
}
}