Repository: maxGraph/maxGraph (ts)

Issue:
GraphDataModel.isLayer: cannot read properties of null (reading 'getParent')
If the parameter "cell" is "null", "null" is returned in the earlier version while an error is reported in the new version.

**report error:**
![image](https://github.com/maxGraph/maxGraph/assets/56530965/b31fb32f-9de8-4b1d-8d15-0fa0a654dd89)



**old version will return "null":**
![image](https://github.com/maxGraph/maxGraph/assets/56530965/ead645e1-ae01-4bb8-8393-ecebcbfadfdb)





Pull request description:
fix: add null check to GraphDataModel::isLayer
**Summary**
`GraphDataModel::isLayer` throws an error if the argument is null, whereas mxgraph would return false. Added a null check to return false in that case, and added some jest tests for `isLayer`. This was noticed in #357

closes #357

**Description for the changelog**
Add null check to GraphDataModel::isLayer


Patch:
diff --git a/packages/core/src/serialization/register.ts b/packages/core/src/serialization/register.ts
index 02e88588d..9dd7b4c8a 100644
--- a/packages/core/src/serialization/register.ts
+++ b/packages/core/src/serialization/register.ts
@@ -104,6 +104,7 @@ export const registerCoreCodecs = (force = false) => {
 
     // mxGraph support
     CodecRegistry.addAlias('mxGraphModel', 'GraphDataModel');
+    CodecRegistry.addAlias('mxPoint', 'Point');
     CodecRegistry.register(new mxCellCodec(), false);
     CodecRegistry.register(new mxGeometryCodec(), false);
 
diff --git a/packages/core/src/view/GraphDataModel.ts b/packages/core/src/view/GraphDataModel.ts
index 269886a0b..948d6e371 100644
--- a/packages/core/src/view/GraphDataModel.ts
+++ b/packages/core/src/view/GraphDataModel.ts
@@ -399,7 +399,7 @@ export class GraphDataModel extends EventSource {
    * @param {Cell} cell  that represents the possible layer.
    */
   isLayer(cell: Cell) {
-    return this.isRoot(cell.getParent());
+    return cell ? this.isRoot(cell.getParent()) : false;
   }
 
   /**


Test patch:
diff --git a/packages/core/__tests__/GraphDataModel.test.ts b/packages/core/__tests__/GraphDataModel.test.ts
new file mode 100644
index 000000000..56832a27b
--- /dev/null
+++ b/packages/core/__tests__/GraphDataModel.test.ts
@@ -0,0 +1,42 @@
+/*
+Copyright 2022-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 { describe, expect, test } from '@jest/globals';
+import { Cell, GraphDataModel } from '../src';
+
+describe('isLayer', () => {
+  const dm: GraphDataModel = new GraphDataModel();
+  const root: Cell = new Cell();
+  dm.setRoot(root);
+
+  test('Child is null', () => {
+    // @ts-ignore
+    const child: Cell = null;
+    expect(dm.isLayer(child)).toBe(false);
+  });
+
+  test('Child is not null and is not layer', () => {
+    const child: Cell = new Cell();
+    expect(dm.isLayer(child)).toBe(false);
+  });
+
+  test('Child is not null and is layer', () => {
+    const child: Cell = new Cell();
+    root.children.push(child);
+    child.setParent(root);
+    expect(dm.isLayer(child)).toBe(true);
+  });
+});
diff --git a/packages/core/__tests__/serialization/serialization.xml.mxGraph.test.ts b/packages/core/__tests__/serialization/serialization.xml.mxGraph.test.ts
index 4c0929780..18829e58a 100644
--- a/packages/core/__tests__/serialization/serialization.xml.mxGraph.test.ts
+++ b/packages/core/__tests__/serialization/serialization.xml.mxGraph.test.ts
@@ -34,7 +34,9 @@ describe('import mxGraph model', () => {
       <mxGeometry x="380" y="20" width="140" height="30" as="geometry"/>
     </mxCell>
     <mxCell id="3" vertex="1" parent="1" value="Vertex #3">
-      <mxGeometry x="200" y="80" width="380" height="30" as="geometry"/>
+      <mxGeometry x="200" y="80" width="380" height="30" as="geometry">
+        <mxPoint x="1" y="1" as="offset"/>
+      </mxGeometry>
     </mxCell>
     <mxCell id="7" edge="1" source="2" target="3" parent="1" value="Edge #7">
       <mxGeometry as="geometry">
@@ -59,8 +61,10 @@ describe('import mxGraph model', () => {
       geometry: new Geometry(380, 20, 140, 30),
     });
 
+    const vertex3Geometry = new Geometry(200, 80, 380, 30);
+    vertex3Geometry.offset = new Point(1, 1);
     modelChecker.expectIsVertex(model.getCell('3'), 'Vertex #3', {
-      geometry: new Geometry(200, 80, 380, 30),
+      geometry: vertex3Geometry,
     });
 
     const edgeGeometry = new Geometry();
diff --git a/packages/core/__tests__/serialization/serialization.xml.test.ts b/packages/core/__tests__/serialization/serialization.xml.test.ts
index 1667dfe8b..f2bfa0ec4 100644
--- a/packages/core/__tests__/serialization/serialization.xml.test.ts
+++ b/packages/core/__tests__/serialization/serialization.xml.test.ts
@@ -71,6 +71,9 @@ const xmlWithVerticesAndEdges = `<GraphDataModel>
       <Object fillColor="green" strokeWidth="4" as="style" />
     </Cell>
     <Cell id="v2" value="vertex 2" vertex="1" parent="1">
+      <Geometry _x="200" _y="50" _width="30" _height="100" as="geometry">
+        <Point _x="30" _y="40" as="offset" />
+      </Geometry>
       <Object bendable="0" rounded="1" fontColor="yellow" as="style" />
     </Cell>
     <Cell id="e1" edge="1" parent="1" source="v1" target="v2">
@@ -109,6 +112,8 @@ describe('import before the export (reproduce https://github.com/maxGraph/maxGra
       },
     });
 
+    const vertexGeometry = new Geometry(200, 50, 30, 100);
+    vertexGeometry.offset = new Point(30, 40);
     modelChecker.expectIsVertex(model.getCell('v2'), 'vertex 2', {
       style: {
         // @ts-ignore FIX should be false
@@ -117,6 +122,7 @@ describe('import before the export (reproduce https://github.com/maxGraph/maxGra
         // @ts-ignore FIX should be true
         rounded: 1,
       },
+      geometry: vertexGeometry,
     });
 
     const edgeGeometry = new Geometry();
@@ -183,6 +189,7 @@ describe('export', () => {
     model.add(parent, v1);
     v1.setStyle({ fillColor: 'green', strokeWidth: 4 });
     v1.geometry = new Geometry(100, 100, 100, 80);
+    v1.geometry.offset = new Point(10, 12);
     const v2 = newVertex('v2', 'vertex 2');
     v2.style = {
       bendable: false,
@@ -213,7 +220,9 @@ describe('export', () => {
       <Object as="style" />
     </Cell>
     <Cell id="v1" value="vertex 1" vertex="1" parent="1">
-      <Geometry _x="100" _y="100" _width="100" _height="80" as="geometry" />
+      <Geometry _x="100" _y="100" _width="100" _height="80" as="geometry">
+        <Point _x="10" _y="12" as="offset" />
+      </Geometry>
       <Object fillColor="green" strokeWidth="4" as="style" />
     </Cell>
     <Cell id="v2" value="vertex 2" vertex="1" parent="1">