2021-12-25 23:39:34 +01:00
|
|
|
/* Copyright [2021] [wisemapping]
|
2021-07-16 16:41:58 +02:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
2021-12-19 17:06:42 +01:00
|
|
|
import {
|
2021-12-30 01:37:58 +01:00
|
|
|
$defined, $assert, createDocument,
|
2021-12-19 17:06:42 +01:00
|
|
|
} from '@wisemapping/core-js';
|
2021-12-02 01:41:56 +01:00
|
|
|
import ModelCodeName from './ModelCodeName';
|
|
|
|
import Mindmap from '../model/Mindmap';
|
2021-12-29 17:38:37 +01:00
|
|
|
import FeatureModelFactory from '../model/FeatureModelFactory';
|
2022-01-03 16:12:12 +01:00
|
|
|
import NodeModel from '../model/NodeModel';
|
2021-10-05 02:05:34 +02:00
|
|
|
|
2021-12-23 20:58:50 +01:00
|
|
|
class XMLSerializerBeta {
|
2022-01-03 16:12:12 +01:00
|
|
|
private static MAP_ROOT_NODE = 'map';
|
|
|
|
|
|
|
|
toXML(mindmap: Mindmap) {
|
2021-10-05 02:05:34 +02:00
|
|
|
$assert(mindmap, 'Can not save a null mindmap');
|
|
|
|
|
2021-12-03 19:58:25 +01:00
|
|
|
const document = createDocument();
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
// Store map attributes ...
|
|
|
|
const mapElem = document.createElement('map');
|
|
|
|
const name = mindmap.getId();
|
|
|
|
if ($defined(name)) {
|
|
|
|
mapElem.setAttribute('name', name);
|
|
|
|
}
|
|
|
|
document.append(mapElem);
|
|
|
|
|
|
|
|
// Create branches ...
|
|
|
|
const topics = mindmap.getBranches();
|
2022-01-03 16:12:12 +01:00
|
|
|
topics.forEach((topic) => {
|
2021-10-05 02:05:34 +02:00
|
|
|
const topicDom = this._topicToXML(document, topic);
|
|
|
|
mapElem.append(topicDom);
|
2022-01-03 16:12:12 +01:00
|
|
|
});
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
return document;
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
2022-01-03 16:12:12 +01:00
|
|
|
_topicToXML(document: Document, topic: NodeModel) {
|
2021-10-05 02:05:34 +02:00
|
|
|
const parentTopic = document.createElement('topic');
|
|
|
|
|
|
|
|
// Set topic attributes...
|
2022-01-02 23:16:18 +01:00
|
|
|
if (topic.getType() === 'CentralTopic') {
|
2022-01-03 16:12:12 +01:00
|
|
|
parentTopic.setAttribute('central', new Boolean(true).toString());
|
2021-10-05 02:05:34 +02:00
|
|
|
} else {
|
|
|
|
const parent = topic.getParent();
|
2022-01-02 23:16:18 +01:00
|
|
|
if (parent == null || parent.getType() === 'CentralTopic') {
|
2021-10-05 02:05:34 +02:00
|
|
|
const pos = topic.getPosition();
|
2021-12-06 00:50:37 +01:00
|
|
|
parentTopic.setAttribute('position', `${pos.x},${pos.y}`);
|
2021-10-05 02:05:34 +02:00
|
|
|
} else {
|
|
|
|
const order = topic.getOrder();
|
2022-01-03 16:12:12 +01:00
|
|
|
parentTopic.setAttribute('order', order.toString());
|
2021-10-05 02:05:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const text = topic.getText();
|
|
|
|
if ($defined(text)) {
|
|
|
|
parentTopic.setAttribute('text', text);
|
|
|
|
}
|
|
|
|
|
|
|
|
const shape = topic.getShapeType();
|
|
|
|
if ($defined(shape)) {
|
|
|
|
parentTopic.setAttribute('shape', shape);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (topic.areChildrenShrunken()) {
|
2022-01-03 16:12:12 +01:00
|
|
|
parentTopic.setAttribute('shrink', new Boolean(true).toString());
|
2021-10-05 02:05:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Font properties ...
|
|
|
|
let font = '';
|
|
|
|
|
|
|
|
const fontFamily = topic.getFontFamily();
|
|
|
|
font += `${fontFamily || ''};`;
|
|
|
|
|
|
|
|
const fontSize = topic.getFontSize();
|
|
|
|
font += `${fontSize || ''};`;
|
|
|
|
|
|
|
|
const fontColor = topic.getFontColor();
|
|
|
|
font += `${fontColor || ''};`;
|
|
|
|
|
|
|
|
const fontWeight = topic.getFontWeight();
|
|
|
|
font += `${fontWeight || ''};`;
|
|
|
|
|
|
|
|
const fontStyle = topic.getFontStyle();
|
|
|
|
font += `${fontStyle || ''};`;
|
|
|
|
|
2021-12-02 01:41:56 +01:00
|
|
|
if (
|
|
|
|
$defined(fontFamily)
|
2021-12-03 19:58:25 +01:00
|
|
|
|| $defined(fontSize)
|
|
|
|
|| $defined(fontColor)
|
|
|
|
|| $defined(fontWeight)
|
|
|
|
|| $defined(fontStyle)
|
2021-12-02 01:41:56 +01:00
|
|
|
) {
|
2021-10-05 02:05:34 +02:00
|
|
|
parentTopic.setAttribute('fontStyle', font);
|
|
|
|
}
|
|
|
|
|
|
|
|
const bgColor = topic.getBackgroundColor();
|
|
|
|
if ($defined(bgColor)) {
|
|
|
|
parentTopic.setAttribute('bgColor', bgColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
const brColor = topic.getBorderColor();
|
|
|
|
if ($defined(brColor)) {
|
|
|
|
parentTopic.setAttribute('brColor', brColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ICONS
|
2022-01-03 16:12:12 +01:00
|
|
|
const icons = topic.findFeatureByType('icons');
|
|
|
|
icons.forEach((icon)=>{
|
2021-10-05 02:05:34 +02:00
|
|
|
const iconDom = this._iconToXML(document, icon);
|
|
|
|
parentTopic.append(iconDom);
|
2022-01-03 16:12:12 +01:00
|
|
|
});
|
|
|
|
|
2021-10-05 02:05:34 +02:00
|
|
|
// LINKS
|
2022-01-03 16:12:12 +01:00
|
|
|
const links = topic.findFeatureByType('links');
|
|
|
|
icons.forEach((link)=>{
|
2021-10-05 02:05:34 +02:00
|
|
|
const linkDom = this._linkToXML(document, link);
|
|
|
|
parentTopic.append(linkDom);
|
2022-01-03 16:12:12 +01:00
|
|
|
});
|
2021-10-05 02:05:34 +02:00
|
|
|
|
2022-01-03 16:12:12 +01:00
|
|
|
const notes = topic.findFeatureByType('note');
|
|
|
|
notes.forEach((note)=>{
|
2021-10-05 02:05:34 +02:00
|
|
|
const noteDom = this._noteToXML(document, note);
|
|
|
|
parentTopic.append(noteDom);
|
2022-01-03 16:12:12 +01:00
|
|
|
});
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
// CHILDREN TOPICS
|
|
|
|
const childTopics = topic.getChildren();
|
2022-01-03 16:12:12 +01:00
|
|
|
childTopics.forEach((childTopic)=>{
|
2021-10-05 02:05:34 +02:00
|
|
|
const childDom = this._topicToXML(document, childTopic);
|
|
|
|
parentTopic.append(childDom);
|
2022-01-03 16:12:12 +01:00
|
|
|
});
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
return parentTopic;
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
_iconToXML(document, icon) {
|
|
|
|
const iconDom = document.createElement('icon');
|
|
|
|
iconDom.setAttribute('id', icon.getIconType());
|
|
|
|
return iconDom;
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
_linkToXML(document, link) {
|
|
|
|
const linkDom = document.createElement('link');
|
|
|
|
linkDom.setAttribute('url', link.getUrl());
|
|
|
|
return linkDom;
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
_noteToXML(document, note) {
|
|
|
|
const noteDom = document.createElement('note');
|
|
|
|
noteDom.setAttribute('text', note.getText());
|
|
|
|
return noteDom;
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
loadFromDom(dom, mapId) {
|
|
|
|
$assert(dom, 'Dom can not be null');
|
|
|
|
$assert(mapId, 'mapId can not be null');
|
|
|
|
|
|
|
|
// Is a valid object ?
|
|
|
|
const { documentElement } = dom;
|
2021-12-02 01:41:56 +01:00
|
|
|
$assert(
|
2021-12-03 19:58:25 +01:00
|
|
|
documentElement.nodeName !== 'parsererror',
|
2021-12-02 01:41:56 +01:00
|
|
|
`Error while parsing: '${documentElement.childNodes[0].nodeValue}`,
|
|
|
|
);
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
// Is a wisemap?.
|
2021-12-02 01:41:56 +01:00
|
|
|
$assert(
|
2021-12-23 20:58:50 +01:00
|
|
|
documentElement.tagName === XMLSerializerBeta.MAP_ROOT_NODE,
|
2021-12-05 00:39:20 +01:00
|
|
|
`This seem not to be a map document. Root Tag: '${documentElement.tagName}',HTML:${dom.innerHTML
|
2022-01-02 19:37:33 +01:00
|
|
|
}, XML:,${new XMLSerializer().serializeToString(dom)}`,
|
2021-12-02 01:41:56 +01:00
|
|
|
);
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
// Start the loading process ...
|
|
|
|
let version = documentElement.getAttribute('version');
|
|
|
|
version = !$defined(version) ? ModelCodeName.BETA : version;
|
|
|
|
const mindmap = new Mindmap(mapId, version);
|
|
|
|
|
|
|
|
const children = documentElement.childNodes;
|
|
|
|
for (let i = 0; i < children.length; i++) {
|
|
|
|
const child = children[i];
|
2021-12-03 19:58:25 +01:00
|
|
|
if (child.nodeType === 1) {
|
2021-10-05 02:05:34 +02:00
|
|
|
const topic = this._deserializeNode(child, mindmap);
|
|
|
|
mindmap.addBranch(topic);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mindmap.setId(mapId);
|
|
|
|
return mindmap;
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
|
|
|
_deserializeNode(domElem, mindmap) {
|
2021-12-02 01:41:56 +01:00
|
|
|
const type = domElem.getAttribute('central') != null
|
2022-01-02 23:16:18 +01:00
|
|
|
? 'CentralTopic'
|
|
|
|
: 'MainTopic';
|
2021-10-05 02:05:34 +02:00
|
|
|
const topic = mindmap.createNode(type);
|
|
|
|
|
|
|
|
// Load attributes...
|
|
|
|
const text = domElem.getAttribute('text');
|
|
|
|
if ($defined(text)) {
|
|
|
|
topic.setText(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
const order = domElem.getAttribute('order');
|
|
|
|
if ($defined(order)) {
|
2021-12-03 19:58:25 +01:00
|
|
|
topic.setOrder(parseInt(order, 10));
|
2021-10-05 02:05:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const shape = domElem.getAttribute('shape');
|
|
|
|
if ($defined(shape)) {
|
|
|
|
topic.setShapeType(shape);
|
|
|
|
}
|
|
|
|
|
|
|
|
const isShrink = domElem.getAttribute('shrink');
|
|
|
|
if ($defined(isShrink)) {
|
|
|
|
topic.setChildrenShrunken(isShrink);
|
|
|
|
}
|
|
|
|
|
|
|
|
const fontStyle = domElem.getAttribute('fontStyle');
|
|
|
|
if ($defined(fontStyle)) {
|
|
|
|
const font = fontStyle.split(';');
|
|
|
|
|
|
|
|
if (font[0]) {
|
|
|
|
topic.setFontFamily(font[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (font[1]) {
|
|
|
|
topic.setFontSize(font[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (font[2]) {
|
|
|
|
topic.setFontColor(font[2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (font[3]) {
|
|
|
|
topic.setFontWeight(font[3]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (font[4]) {
|
|
|
|
topic.setFontStyle(font[4]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const bgColor = domElem.getAttribute('bgColor');
|
|
|
|
if ($defined(bgColor)) {
|
|
|
|
topic.setBackgroundColor(bgColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
const borderColor = domElem.getAttribute('brColor');
|
|
|
|
if ($defined(borderColor)) {
|
|
|
|
topic.setBorderColor(borderColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
const position = domElem.getAttribute('position');
|
|
|
|
if ($defined(position)) {
|
|
|
|
const pos = position.split(',');
|
|
|
|
topic.setPosition(pos[0], pos[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Creating icons and children nodes
|
|
|
|
const children = domElem.childNodes;
|
|
|
|
for (let i = 0; i < children.length; i++) {
|
|
|
|
const child = children[i];
|
2021-12-03 19:58:25 +01:00
|
|
|
if (child.nodeType === 1) {
|
2021-12-02 01:41:56 +01:00
|
|
|
$assert(
|
2021-12-03 19:58:25 +01:00
|
|
|
child.tagName === 'topic'
|
|
|
|
|| child.tagName === 'icon'
|
|
|
|
|| child.tagName === 'link'
|
|
|
|
|| child.tagName === 'note',
|
2021-12-02 01:41:56 +01:00
|
|
|
`Illegal node type:${child.tagName}`,
|
|
|
|
);
|
2021-12-03 19:58:25 +01:00
|
|
|
if (child.tagName === 'topic') {
|
2021-10-05 02:05:34 +02:00
|
|
|
const childTopic = this._deserializeNode(child, mindmap);
|
|
|
|
childTopic.connectTo(topic);
|
2021-12-03 19:58:25 +01:00
|
|
|
} else if (child.tagName === 'icon') {
|
2022-01-03 16:12:12 +01:00
|
|
|
const icon = this._deserializeIcon(child);
|
2021-10-05 02:05:34 +02:00
|
|
|
topic.addFeature(icon);
|
2021-12-03 19:58:25 +01:00
|
|
|
} else if (child.tagName === 'link') {
|
2022-01-03 16:12:12 +01:00
|
|
|
const link = this._deserializeLink(child);
|
2021-10-05 02:05:34 +02:00
|
|
|
topic.addFeature(link);
|
2021-12-03 19:58:25 +01:00
|
|
|
} else if (child.tagName === 'note') {
|
2022-01-03 16:12:12 +01:00
|
|
|
const note = this._deserializeNote(child);
|
2021-10-05 02:05:34 +02:00
|
|
|
topic.addFeature(note);
|
2021-07-16 16:41:58 +02:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return topic;
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
2022-01-03 16:12:12 +01:00
|
|
|
_deserializeIcon(domElem: Element) {
|
2021-10-05 02:05:34 +02:00
|
|
|
let icon = domElem.getAttribute('id');
|
|
|
|
icon = icon.replace('images/', 'icons/legacy/');
|
2022-01-03 16:12:12 +01:00
|
|
|
return FeatureModelFactory.createModel('icon', { id: icon });
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
2022-01-03 16:12:12 +01:00
|
|
|
_deserializeLink(domElem: Element) {
|
|
|
|
return FeatureModelFactory.createModel('link', { url: domElem.getAttribute('url') });
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
2021-10-05 02:05:34 +02:00
|
|
|
|
2022-01-03 16:12:12 +01:00
|
|
|
_deserializeNote(domElem: Element) {
|
2021-10-05 02:05:34 +02:00
|
|
|
const text = domElem.getAttribute('text');
|
2022-01-03 16:12:12 +01:00
|
|
|
return FeatureModelFactory.createModel('note', { text: text == null ? ' ' : text });
|
2021-12-05 00:39:20 +01:00
|
|
|
}
|
|
|
|
}
|
2021-07-16 16:41:58 +02:00
|
|
|
|
|
|
|
|
2021-12-23 20:58:50 +01:00
|
|
|
export default XMLSerializerBeta;
|