feat: add `ModelXmlSerializer` to import/export the model (#290)

This class was previously only available in test. It simplifies maxGraph
model import/export as:
  - it hides `Codec` and `HTMLElement` management
  - it registers codecs automagically
development
Thomas Bouffard 2023-12-18 15:53:43 +01:00 committed by GitHub
parent f9b2d7d19a
commit 99ffdfa29b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 80 additions and 42 deletions

View File

@ -9,6 +9,8 @@ You can use one of the following functions to register codecs:
- `registerCoreCodecs` - `registerCoreCodecs`
- `registerEditorCodecs` - `registerEditorCodecs`
To serialize the `maxGraph` model, you can use the `ModelXmlSerializer` class, which registers codecs under the hood.
## 0.5.0 ## 0.5.0
Release date: `2023-12-07` Release date: `2023-12-07`

View File

@ -16,47 +16,7 @@ limitations under the License.
import { describe, expect, test } from '@jest/globals'; import { describe, expect, test } from '@jest/globals';
import { createGraphWithoutContainer } from '../utils'; import { createGraphWithoutContainer } from '../utils';
import { import { Cell, Geometry, GraphDataModel, ModelXmlSerializer, Point } from '../../src';
Cell,
Codec,
Geometry,
GraphDataModel,
Point,
registerCoreCodecs,
} from '../../src';
import { getPrettyXml, parseXml } from '../../src/util/xmlUtils';
type ModelExportOptions = {
/**
* @default true
*/
pretty?: boolean;
};
/**
* Convenient utility class using {@link Codec} to manage maxGraph model import and export.
*
* @internal
* @alpha subject to change (class and method names)
*/
class ModelXmlSerializer {
// Include 'XML' in the class name as there were past discussions about supporting other format (JSON for example {@link https://github.com/maxGraph/maxGraph/discussions/60}).
constructor(private dataModel: GraphDataModel) {
registerCoreCodecs();
}
import(xml: string): void {
const doc = parseXml(xml);
new Codec(doc).decode(doc.documentElement, this.dataModel);
}
export(options?: ModelExportOptions): string {
const encodedNode = new Codec().encode(this.dataModel);
return options?.pretty ?? true
? getPrettyXml(encodedNode)
: getPrettyXml(encodedNode, '', '', '');
}
}
// inspired by VertexMixin.createVertex // inspired by VertexMixin.createVertex
const newVertex = (id: string, value: string) => { const newVertex = (id: string, value: string) => {

View File

@ -114,6 +114,7 @@ export { default as SwimlaneOrdering } from './view/layout/hierarchical/Swimlane
export { default as Codec } from './serialization/Codec'; export { default as Codec } from './serialization/Codec';
export { default as CodecRegistry } from './serialization/CodecRegistry'; export { default as CodecRegistry } from './serialization/CodecRegistry';
export { default as ObjectCodec } from './serialization/ObjectCodec'; export { default as ObjectCodec } from './serialization/ObjectCodec';
export * from './serialization/ModelXmlSerializer';
export * from './serialization/codecs'; export * from './serialization/codecs';
export * from './serialization/register'; export * from './serialization/register';

View File

@ -0,0 +1,73 @@
/*
Copyright 2023-present The maxGraph project Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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.
*/
import { registerCoreCodecs } from './register';
import { getPrettyXml, parseXml } from '../util/xmlUtils';
import { Codec } from '../index';
import type GraphDataModel from '../view/GraphDataModel';
/**
* Export options of {@link ModelXmlSerializer}.
*
* **WARN**: this is an experimental feature that is subject to change.
*
* @alpha
* @experimental
* @since 0.6.0
*/
export type ModelExportOptions = {
/**
* If `true`, prettify the exported xml.
* @default true
*/
pretty?: boolean;
};
/**
* Convenient utility class using {@link Codec} to manage maxGraph model import and export.
*
* **WARN**: this is an experimental feature that is subject to change (class and method names).
*
* @alpha
* @experimental
* @since 0.6.0
*/
// Include 'XML' in the class name as there were past discussions about supporting other format like JSON for example
// See https://github.com/maxGraph/maxGraph/discussions/60 for more details.
export class ModelXmlSerializer {
constructor(private dataModel: GraphDataModel) {
this.registerCodecs();
}
import(xml: string): void {
const doc = parseXml(xml);
new Codec(doc).decode(doc.documentElement, this.dataModel);
}
export(options?: ModelExportOptions): string {
const encodedNode = new Codec().encode(this.dataModel);
return options?.pretty ?? true
? getPrettyXml(encodedNode)
: getPrettyXml(encodedNode, '', '', '');
}
/**
* Hook for replacing codecs registered by default (core codecs).
*/
protected registerCodecs(): void {
registerCoreCodecs();
}
}

View File

@ -541,7 +541,9 @@ This is currently not supported in maxGraph: https://github.com/maxGraph/maxGrap
From version 0.6.0 of `maxGraph`, codecs supplied by maxGraph are no longer registered by default, they ** MUST** be registered before performing an `encode` or `decode` From version 0.6.0 of `maxGraph`, codecs supplied by maxGraph are no longer registered by default, they ** MUST** be registered before performing an `encode` or `decode`
For example, you can use the `registerCoreCodecs` function (or other related functions) to register codecs. For example:
- You can use the `registerCoreCodecs` function (or other related functions) to register codecs.
- To serialize the `maxGraph` model, you can use the `ModelXmlSerializer` class, which registers codecs under the hood.
::: :::