Skip to content

refactor: use "for of" loop in the plugin folder#896

Draft
tbouffard wants to merge 6 commits intomainfrom
refactor/simplify_loop_in_plugins
Draft

refactor: use "for of" loop in the plugin folder#896
tbouffard wants to merge 6 commits intomainfrom
refactor/simplify_loop_in_plugins

Conversation

@tbouffard
Copy link
Copy Markdown
Member

@tbouffard tbouffard commented Aug 1, 2025

Prefer the use of for-of loop over the standard for loop where possible.
This simplifies the syntax and make the code easier to read.

Tasks

  • add some tests
  • restore usage of cell.getChildrenCount/getCellAt. To confirm if we consider they are extension points that must be used here. This is part of Define the Public API #854, to decide if we want to restore the related method that formerly existed in the Model class in mxGraph and that has been removed as part of the migration.
  • configure an eslint rule to enforce this progressively in the code of the core module, for example https://typescript-eslint.io/rules/prefer-for-of/

Summary by CodeRabbit

  • Refactor
    • Improved code readability by updating array iteration style to use more concise looping syntax in various features. No changes to functionality or user experience.

Prefer the use of for-of loop over the standard for loop where possible.
This simplifies the syntax and make the code easier to read.
@tbouffard tbouffard added the refactor Code refactoring label Aug 1, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Aug 1, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Traditional indexed for-loops were replaced with modern for-of loops across three core plugin files. Variable names within these loops were clarified for readability. No logic, control flow, or public API changes were introduced; the updates focus solely on iteration syntax and code clarity.

Changes

Cohort / File(s) Change Summary
ConnectionHandler for-of Refactor
packages/core/src/view/plugins/ConnectionHandler.ts
Replaced indexed for-loops with for-of loops in destroyIcons() and connect() for array iteration clarity.
SelectionCellsHandler Loop & Naming Update
packages/core/src/view/plugins/SelectionCellsHandler.ts
Changed variable name from tmp to cells and switched to for-of loops for improved readability in refresh().
SelectionHandler for-of Refactor
packages/core/src/view/plugins/SelectionHandler.ts
Updated all array iterations to use for-of loops and clarified loop variable names across multiple methods.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Suggested labels

enhancement

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/simplify_loop_in_plugins

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@tbouffard tbouffard marked this pull request as draft August 1, 2025 17:31
@tbouffard
Copy link
Copy Markdown
Member Author

ℹ️ Converted to Draft, I am going to add some tests

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Aug 4, 2025

const state = new CellState(graph.view, cell, {});
graph.view.getState = () => state;

const dict = new Map<Cell, CellState>();
Copy link
Copy Markdown
Member Author

@tbouffard tbouffard Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: rename dic to cellStates for clarity. We are not using a Dictionary type (which has been removed) and it is clearer to name the variable with the context it holds instead of using a name related to a type.
NOTE: this applies to all tests in this file

* var changes = evt.getProperty('edit').changes;
* var nodes = [];
* var codec = new Codec();
* model.addListener(mxEvent.CHANGE, function(sender, evt) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: mxEvent does not exist, this is a mxGraph value

NOTE: this applies to all references in this file

* @param cell
* @param dict
*/
addStates(cell: Cell, dict: Map<Cell, CellState>) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: rename parameter, see remark about the dic variable


/**
* Suspends the livew preview.
* Suspends the live preview.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion:

Suggested change
* Suspends the live preview.
* Resumes the live preview.

for (let i = 0; i < parents.length; i += 1) {
if (this.shouldRemoveParent(parents[i])) {
temp.push(parents[i]);
for (const aParent of parents) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: use a filter method on the original array (add tests before doing the refactoring)

Comment on lines -791 to -794
const childCount = cell.getChildCount();

for (let i = 0; i < childCount; i += 1) {
count += this.addStates(cell.getChildAt(i), dict);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo: add tests here and for all methods where using direct loop instead of using cell.getChildCount and cell.getChildAt

Comment on lines +1180 to +1185
const points: Point[] = [];

if (geometry?.points) {
const geometryPoints = geometry.points;
for (const point of geometryPoints) {
point && points.push(new Point(point.x + dx / s, point.y + dy / s));
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: use a filter and map methods on the original array

@@ -1552,17 +1555,17 @@ class SelectionHandler implements GraphPlugin, MouseListenerSet {
// Collects all non-selected parents
const dict = new Map<Cell, boolean>();
Copy link
Copy Markdown
Member Author

@tbouffard tbouffard Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to detectedParents or foundParents or nonSelectedParents, ...

let graph: AbstractGraph;
let plugin: SelectionHandler;

beforeEach(() => {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add afterEach to destroy the graph and release resources

@sonarqubecloud
Copy link
Copy Markdown

@tbouffard tbouffard changed the title refactor: use "for of" loop in plugins when possible refactor: use "for of" loop in the "plugin" folder when possible Dec 19, 2025
@tbouffard tbouffard changed the title refactor: use "for of" loop in the "plugin" folder when possible refactor: use "for of" loop in the plugin folder Dec 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor Code refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant