From 99ffdfa29b467056844688ff520663ec30b0eca2 Mon Sep 17 00:00:00 2001 From: Thomas Bouffard <27200110+tbouffard@users.noreply.github.com> Date: Mon, 18 Dec 2023 15:53:43 +0100 Subject: [PATCH] feat: add `ModelXmlSerializer` to import/export the model (#290) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- CHANGELOG.md | 2 + .../serialization/serialization.xml.test.ts | 42 +---------- packages/core/src/index.ts | 1 + .../src/serialization/ModelXmlSerializer.ts | 73 +++++++++++++++++++ .../docs/usage/migrate-from-mxgraph.md | 4 +- 5 files changed, 80 insertions(+), 42 deletions(-) create mode 100644 packages/core/src/serialization/ModelXmlSerializer.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b884f4b5..1ac0c12ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ You can use one of the following functions to register codecs: - `registerCoreCodecs` - `registerEditorCodecs` +To serialize the `maxGraph` model, you can use the `ModelXmlSerializer` class, which registers codecs under the hood. + ## 0.5.0 Release date: `2023-12-07` diff --git a/packages/core/__tests__/serialization/serialization.xml.test.ts b/packages/core/__tests__/serialization/serialization.xml.test.ts index 13b26c9d2..edaec3866 100644 --- a/packages/core/__tests__/serialization/serialization.xml.test.ts +++ b/packages/core/__tests__/serialization/serialization.xml.test.ts @@ -16,47 +16,7 @@ limitations under the License. import { describe, expect, test } from '@jest/globals'; import { createGraphWithoutContainer } from '../utils'; -import { - 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, '', '', ''); - } -} +import { Cell, Geometry, GraphDataModel, ModelXmlSerializer, Point } from '../../src'; // inspired by VertexMixin.createVertex const newVertex = (id: string, value: string) => { diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 33ee0a5cd..1a8b55432 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -114,6 +114,7 @@ export { default as SwimlaneOrdering } from './view/layout/hierarchical/Swimlane export { default as Codec } from './serialization/Codec'; export { default as CodecRegistry } from './serialization/CodecRegistry'; export { default as ObjectCodec } from './serialization/ObjectCodec'; +export * from './serialization/ModelXmlSerializer'; export * from './serialization/codecs'; export * from './serialization/register'; diff --git a/packages/core/src/serialization/ModelXmlSerializer.ts b/packages/core/src/serialization/ModelXmlSerializer.ts new file mode 100644 index 000000000..770a1b9ec --- /dev/null +++ b/packages/core/src/serialization/ModelXmlSerializer.ts @@ -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(); + } +} diff --git a/packages/website/docs/usage/migrate-from-mxgraph.md b/packages/website/docs/usage/migrate-from-mxgraph.md index a33253776..3e4907397 100644 --- a/packages/website/docs/usage/migrate-from-mxgraph.md +++ b/packages/website/docs/usage/migrate-from-mxgraph.md @@ -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` -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. :::