Repository: maxGraph/maxGraph
Pull request #448 (2024-06-07 15:35:50)

refactor!: `cellArrayUtils.cloneCells` returns an array of Cells
Previously, it was returning a function. This created an extra indirections whereas the cells can be directly pass to the function.
This also restore the signature that existed in mxGraph, so it will ease the migration.

BREAKING CHANGES: the signature of `cellArrayUtils.cloneCells` has changed.



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1cfe782ed..c74a9be26 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ GlobalConfig.logger = new MaxLogAsLogger();
 - The signature of `cellArrayUtils.getOpposites` has changed. It now returns an array and take an edges Cell array parameter.
 Previously it was returning a function and this was an extra indirection. This is now simpler to use and match the signature of the mxGraph function.
 - `cellArrayUtils.restoreClone` is no longer available. It was intended to be private.
+- The signature of `cellArrayUtils.cloneCells` has changed. It now returns an array of Cells instead of a function. 
 
 ## 0.10.3
 
diff --git a/packages/core/src/util/cellArrayUtils.ts b/packages/core/src/util/cellArrayUtils.ts
index f9651f40d..9a95dbbb9 100644
--- a/packages/core/src/util/cellArrayUtils.ts
+++ b/packages/core/src/util/cellArrayUtils.ts
@@ -114,26 +114,29 @@ export const getParents = (cells: Cell[]) => {
  * each cell. Connections are restored based if the corresponding
  * cell is contained in the provided in array.
  *
+ * @param cells The cells to clone
  * @param includeChildren  Boolean indicating if the cells should be cloned with all descendants.
  * @param mapping  Optional mapping for existing clones.
  */
-export const cloneCells =
-  (includeChildren = true, mapping: any = {}) =>
-  (cells: Cell[]) => {
-    const clones = [] as Cell[];
+export const cloneCells = (
+  cells: Cell[],
+  includeChildren = true,
+  mapping: any = {}
+): Cell[] => {
+  const clones = [] as Cell[];
 
-    for (const cell of cells) {
-      clones.push(cloneCellImpl(cell, mapping, includeChildren));
-    }
+  for (const cell of cells) {
+    clones.push(cloneCellImpl(cell, mapping, includeChildren));
+  }
 
-    for (let i = 0; i < clones.length; i += 1) {
-      if (clones[i] != null) {
-        restoreClone(<Cell>clones[i], cells[i], mapping);
-      }
+  for (let i = 0; i < clones.length; i += 1) {
+    if (clones[i] != null) {
+      restoreClone(<Cell>clones[i], cells[i], mapping);
     }
+  }
 
-    return clones;
-  };
+  return clones;
+};
 
 /**
  * Inner helper method for cloning cells recursively.
diff --git a/packages/core/src/view/GraphDataModel.ts b/packages/core/src/view/GraphDataModel.ts
index bd57f01ad..5f7873f0e 100644
--- a/packages/core/src/view/GraphDataModel.ts
+++ b/packages/core/src/view/GraphDataModel.ts
@@ -1193,7 +1193,7 @@ export class GraphDataModel extends EventSource {
       return null;
     }
 
-    return cloneCells(includeChildren)([cell])[0];
+    return cloneCells([cell], includeChildren)[0];
   }
 }
 
diff --git a/packages/core/src/view/mixins/CellsMixin.ts b/packages/core/src/view/mixins/CellsMixin.ts
index 28c08680c..1648cfe55 100644
--- a/packages/core/src/view/mixins/CellsMixin.ts
+++ b/packages/core/src/view/mixins/CellsMixin.ts
@@ -920,7 +920,7 @@ export const CellsMixin: PartialType = {
       const { scale } = this.getView();
       const trans = this.getView().translate;
       const out: Cell[] = [];
-      clones = cloneCells(true, mapping)(cells);
+      clones = cloneCells(cells, true, mapping);
 
       for (let i = 0; i < cells.length; i += 1) {
         const cell = cells[i];


Test patch:
diff --git a/packages/core/__tests__/util/cellArrayUtils.test.ts b/packages/core/__tests__/util/cellArrayUtils.test.ts
index 613e77d34..f06c4e334 100644
--- a/packages/core/__tests__/util/cellArrayUtils.test.ts
+++ b/packages/core/__tests__/util/cellArrayUtils.test.ts
@@ -89,7 +89,7 @@ describe('cloneCells', () => {
       // @ts-ignore
       expect(cell[IDENTITY_FIELD_NAME]).toBeUndefined();
 
-      const clones = cloneCells(includeChildren)([cell, source]);
+      const clones = cloneCells([cell, source], includeChildren);
       expect(clones).toHaveLength(2);
 
       expect(cell.getParent()).toBeNull(); // untouched