Skip to content

refactor!: move getViewXml from xmlUtils to xmlViewUtils#992

Merged
tbouffard merged 3 commits intomainfrom
refactor/move_xmlView
Jan 9, 2026
Merged

refactor!: move getViewXml from xmlUtils to xmlViewUtils#992
tbouffard merged 3 commits intomainfrom
refactor/move_xmlView

Conversation

@tbouffard
Copy link
Copy Markdown
Member

@tbouffard tbouffard commented Jan 8, 2026

The getViewXml function depends on high-level APIs (Codec, TemporaryCellStates) and is only used by the Editor class.
Moving it to a dedicated xmlViewUtils module improves separation of concerns:

  • xmlUtils remains focused on low-level XML parsing utilities
  • xmlViewUtils handles view-specific XML serialization

BREAKING CHANGE: xmlUtils.getViewXml moved to xmlViewUtils.getViewXml.

Summary by CodeRabbit

  • Refactor

    • Internal XML utilities reorganized for clearer separation of view-specific logic.
  • New Features

    • Added a dedicated view-serialization utility to export the current diagram view as XML.
  • Improvements

    • View export now handles both SVG and non‑SVG renderers, reliably restores view state and events after export, and falls back to exporting the full root view when nothing is selected.

✏️ Tip: You can customize this high-level summary in your review settings.

The getViewXml function depends on high-level APIs (Codec, TemporaryCellStates) and is only used by the Editor class.
Moving it to a dedicated xmlViewUtils module improves separation of concerns:
  - xmlUtils remains focused on low-level XML parsing utilities
  - xmlViewUtils handles view-specific XML serialization

BREAKING CHANGE: xmlUtils.getViewXml moved to xmlViewUtils.getViewXml.
@tbouffard tbouffard added the refactor Code refactoring label Jan 8, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 8, 2026

Walkthrough

Moved view-serialization logic into a new module xmlViewUtils.ts. Editor.ts now imports getViewXml from the new module; index.ts exposes xmlViewUtils. xmlUtils.ts had getViewXml removed and createXmlDocument() return typed as XMLDocument.

Changes

Cohort / File(s) Summary
View serialization module added
packages/core/src/util/xmlViewUtils.ts
New file exporting `getViewXml(graph, scale = 1, cells = null, x0 = 0, y0 = 0): Element
Core XML utilities modified
packages/core/src/util/xmlUtils.ts
Removed view-specific getViewXml and related imports; retained getXml, getPrettyXml, findNode. Updated createXmlDocument(): XMLDocument signature and simplified imports.
Editor import updates
packages/core/src/editor/Editor.ts
Import changed: now imports getViewXml from ../util/xmlViewUtils.js and getXml remains from ../util/xmlUtils.js.
Public exports extended
packages/core/src/index.ts
Added export * as xmlViewUtils from './util/xmlViewUtils.js'; to export the new namespace alongside existing xmlUtils.
Changelog
CHANGELOG.md
Added breaking-change note documenting the move of getViewXml from xmlUtils to xmlViewUtils.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Editor
participant xmlViewUtils as xmlViewUtils.getViewXml
participant Graph
participant TempStates as TemporaryCellStates
participant Codec
Editor->>xmlViewUtils: getViewXml(graph, scale, cells, x0, y0)
xmlViewUtils->>Graph: disableEvents(); save view state; set translate(x0,y0); create temp panes
xmlViewUtils->>TempStates: build temporary cell states for target cells
xmlViewUtils->>Codec: encode(view, tempStates)
Codec-->>xmlViewUtils: XML Element | null
xmlViewUtils->>Graph: restore view state; remove temp panes; enableEvents()
xmlViewUtils-->>Editor: return XML Element | null

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description lacks most required template sections. Missing: issue reference, PR checklist items, detailed scope explanation, tests/evidence, documentation changes, and proper conventional commits validation. Add issue reference (closes/fixes #), check all PR checklist items, clarify scope, document test coverage, and confirm all template requirements are addressed.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main refactoring change: moving getViewXml from xmlUtils to xmlViewUtils module, which is the primary objective of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

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

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.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/core/src/util/xmlUtils.ts (1)

28-30: Add explicit return type annotation.

Per coding guidelines, TypeScript source files in the core package must have explicit return type annotations on all functions.

Suggested fix
-export const createXmlDocument = () => {
+export const createXmlDocument = (): Document => {
   return document.implementation.createDocument('', '', null);
 };
packages/core/src/util/xmlViewUtils.ts (2)

26-32: Add explicit return type annotation.

Per coding guidelines, TypeScript functions in the core package must have explicit return type annotations. The current signature lacks a return type.

Suggested fix
 export const getViewXml = (
   graph: AbstractGraph,
   scale = 1,
   cells: Cell[] | null = null,
   x0 = 0,
   y0 = 0
-) => {
+): Element | null => {

Note: The actual return type depends on what Codec.encode() returns. If it returns any, you may want to keep it as any or use a more specific type based on the Codec's actual behavior.


33-36: Null handling for getRoot() could be more defensive.

The type assertion <Cell>model.getRoot() assumes the root is never null. While this is typically true for initialized graphs, a defensive check could improve robustness.

This is a minor concern since the original code had the same pattern, and per learnings, this PR is focused on code reorganization without implementation changes.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42384ac and 5d77705.

📒 Files selected for processing (4)
  • packages/core/src/editor/Editor.ts
  • packages/core/src/index.ts
  • packages/core/src/util/xmlUtils.ts
  • packages/core/src/util/xmlViewUtils.ts
🧰 Additional context used
📓 Path-based instructions (6)
packages/core/src/**/*.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/core/src/**/*.ts: Include .js file extensions in all import statements within packages/core/src/ to comply with ESLint rule n/file-extension-in-import.
Do not use console statements in any code. Use proper logging mechanisms instead (ESLint rule: no-console: error).
Do not use eval() function in any code (ESLint rule: no-eval: error).
Do not use const enums. Convert all const enums to regular enums (ESLint rule forbids const enums).
TypeScript source files in core package must strictly maintain typing with no implicit types and all functions having explicit return type annotations.

Use singular form for folder names (e.g., handler/ not handlers/) and kebab-case for folder names (e.g., my-feature/ not myFeature/ or my_feature/)

Files:

  • packages/core/src/util/xmlUtils.ts
  • packages/core/src/index.ts
  • packages/core/src/util/xmlViewUtils.ts
  • packages/core/src/editor/Editor.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use single quotes in TypeScript/JavaScript code (Prettier config: singleQuote: true).

Files:

  • packages/core/src/util/xmlUtils.ts
  • packages/core/src/index.ts
  • packages/core/src/util/xmlViewUtils.ts
  • packages/core/src/editor/Editor.ts
**/*.{ts,tsx,js,jsx,json,md}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Format code using Prettier with tab width 2, trailing comma ES5, print width 90, and end of line auto.

Files:

  • packages/core/src/util/xmlUtils.ts
  • packages/core/src/index.ts
  • packages/core/src/util/xmlViewUtils.ts
  • packages/core/src/editor/Editor.ts
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Use the isNullish() function when checking for null or undefined on variables that can have falsy values (numbers, strings, booleans) to avoid bugs where 0, "", or false are incorrectly treated as nullish
Use the log() function from internal/utils.js instead of accessing GlobalConfig.logger directly for logging
Use functions translate() and isI18nEnabled() from internal/i18n-utils.js instead of accessing GlobalConfig.i18n directly for internationalization
Always wrap multiple model changes in batchUpdate() to ensure efficient graph updates

Files:

  • packages/core/src/util/xmlUtils.ts
  • packages/core/src/index.ts
  • packages/core/src/util/xmlViewUtils.ts
  • packages/core/src/editor/Editor.ts
**/*.{ts,js}

📄 CodeRabbit inference engine (CLAUDE.md)

Prefer using BaseGraph in production with explicit feature registration for optimal tree-shaking and minimal bundle size; use Graph only for prototyping and demos with automatic defaults

Files:

  • packages/core/src/util/xmlUtils.ts
  • packages/core/src/index.ts
  • packages/core/src/util/xmlViewUtils.ts
  • packages/core/src/editor/Editor.ts
packages/core/src/**

📄 CodeRabbit inference engine (CLAUDE.md)

Organize code using the mixin pattern where each mixin provides a specific capability with two files: implementation (.ts) and type definitions (.type.ts), with unified type definitions in _graph-mixins-types.ts

Files:

  • packages/core/src/util/xmlUtils.ts
  • packages/core/src/index.ts
  • packages/core/src/util/xmlViewUtils.ts
  • packages/core/src/editor/Editor.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: tbouffard
Repo: maxGraph/maxGraph PR: 740
File: packages/core/src/util/requestUtils.ts:79-106
Timestamp: 2025-03-31T08:32:17.055Z
Learning: PR #740 is focused on reorganizing code into namespaces (guiUtils and requestUtils) without changing any implementations. Implementation improvements should be suggested for future PRs.
Learnt from: tbouffard
Repo: maxGraph/maxGraph PR: 857
File: packages/core/src/view/plugins/SelectionHandler.ts:1081-1092
Timestamp: 2025-06-26T13:27:19.012Z
Learning: User tbouffard prefers to keep PRs focused on their main objective and defer implementation improvements or logic fixes to future dedicated PRs. For maxGraph, refactoring PRs like Dictionary→Map migration should not include unrelated logic improvements even when valid issues are identified in the migrated code.
Learnt from: tbouffard
Repo: maxGraph/maxGraph PR: 776
File: packages/core/src/view/AbstractGraph.ts:492-495
Timestamp: 2025-04-24T12:34:56.726Z
Learning: PR #776 focuses on refactoring to introduce AbstractGraph as a base class and moving code from Graph to AbstractGraph. Type improvements and other refinements should be addressed in future PRs to keep this one focused on the core architectural change.
Learnt from: tbouffard
Repo: maxGraph/maxGraph PR: 849
File: packages/html/stories/DragSource.stories.js:98-101
Timestamp: 2025-06-13T07:48:10.300Z
Learning: User tbouffard prefers answers in English; avoid switching to other languages in future replies.
📚 Learning: 2025-03-31T08:32:17.055Z
Learnt from: tbouffard
Repo: maxGraph/maxGraph PR: 740
File: packages/core/src/util/requestUtils.ts:79-106
Timestamp: 2025-03-31T08:32:17.055Z
Learning: PR #740 is focused on reorganizing code into namespaces (guiUtils and requestUtils) without changing any implementations. Implementation improvements should be suggested for future PRs.

Applied to files:

  • packages/core/src/index.ts
🧬 Code graph analysis (1)
packages/core/src/util/xmlViewUtils.ts (1)
packages/core/src/util/Constants.ts (1)
  • NS_SVG (52-52)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build (windows-2022)
  • GitHub Check: build (macos-14)
  • GitHub Check: build (ubuntu-24.04)
🔇 Additional comments (5)
packages/core/src/util/xmlUtils.ts (1)

19-23: Clean import cleanup after refactoring.

The imports are correctly updated to remove dependencies that were only needed by the moved getViewXml function. The StyleValue type import is correctly preserved as a type-only import.

packages/core/src/index.ts (1)

183-186: New public API export follows existing conventions.

The new xmlViewUtils export is correctly placed after the existing xmlUtils export, follows the same pattern with JSDoc category annotation, and uses the .js extension in the import path as required.

packages/core/src/editor/Editor.ts (1)

48-49: Import update correctly reflects module reorganization.

The imports are properly split between xmlUtils (for getXml) and xmlViewUtils (for getViewXml), both with correct .js extensions. The usage in the exportImage action remains unchanged.

packages/core/src/util/xmlViewUtils.ts (2)

74-85: Well-structured cleanup ensures view state restoration.

The try/finally block properly ensures all temporary state is cleaned up regardless of whether encoding succeeds or fails. This includes destroying temporary cell states, restoring the translate, removing temporary panes, restoring original panes, and re-enabling events.


19-24: Imports correctly structured with .js extensions.

All imports use the required .js extension and appropriately use type imports for Cell and AbstractGraph since they are only used in type positions.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Jan 8, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
CHANGELOG.md (1)

15-15: Consider wrapping the line to fit the print width guideline.

Line 15 exceeds the Prettier print width of 90 characters (currently ~165 characters). While the content is accurate and well-documented, wrapping it would align with the project's formatting standards.

Suggested line wrap
-- `xmlUtils.getViewXml` moved to `xmlViewUtils.getViewXml`. The impact should be limited as this function was not widely used (only in the Editor class in the maxGraph code).
+- `xmlUtils.getViewXml` moved to `xmlViewUtils.getViewXml`. The impact should be
+  limited as this function was not widely used (only in the Editor class in the
+  maxGraph code).
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 49918f4 and a1eb07c.

📒 Files selected for processing (1)
  • CHANGELOG.md
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js,jsx,json,md}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Format code using Prettier with tab width 2, trailing comma ES5, print width 90, and end of line auto.

Files:

  • CHANGELOG.md
🧠 Learnings (1)
📓 Common learnings
Learnt from: tbouffard
Repo: maxGraph/maxGraph PR: 740
File: packages/core/src/util/requestUtils.ts:79-106
Timestamp: 2025-03-31T08:32:17.055Z
Learning: PR #740 is focused on reorganizing code into namespaces (guiUtils and requestUtils) without changing any implementations. Implementation improvements should be suggested for future PRs.
Learnt from: tbouffard
Repo: maxGraph/maxGraph PR: 776
File: packages/core/src/view/AbstractGraph.ts:492-495
Timestamp: 2025-04-24T12:34:56.726Z
Learning: PR #776 focuses on refactoring to introduce AbstractGraph as a base class and moving code from Graph to AbstractGraph. Type improvements and other refinements should be addressed in future PRs to keep this one focused on the core architectural change.
Learnt from: tbouffard
Repo: maxGraph/maxGraph PR: 857
File: packages/core/src/view/plugins/SelectionHandler.ts:1081-1092
Timestamp: 2025-06-26T13:27:19.012Z
Learning: User tbouffard prefers to keep PRs focused on their main objective and defer implementation improvements or logic fixes to future dedicated PRs. For maxGraph, refactoring PRs like Dictionary→Map migration should not include unrelated logic improvements even when valid issues are identified in the migrated code.
Learnt from: tbouffard
Repo: maxGraph/maxGraph PR: 849
File: packages/html/stories/DragSource.stories.js:98-101
Timestamp: 2025-06-13T07:48:10.300Z
Learning: User tbouffard prefers answers in English; avoid switching to other languages in future replies.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build (macos-14)
  • GitHub Check: build (windows-2022)
  • GitHub Check: build (ubuntu-24.04)
  • GitHub Check: build

@tbouffard tbouffard merged commit 6a55ac0 into main Jan 9, 2026
11 checks passed
@tbouffard tbouffard deleted the refactor/move_xmlView branch January 9, 2026 09:35
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